Java NotOLE2FileException: 无效的标头签名;读取 0x0000000000000000,预期为 0xE11AB1A1E011CFD0
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33879515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0
提问by Wabbage
What I want to do is ask the user if they want to create a new or select an existing Excel workbook. Selecting an existing file is no problem. However I get an error saying "Your file appears not to be a valid OLE2 document" as soon as I create a name for a new Excel file.
我想要做的是询问用户是否要创建新的或选择现有的 Excel 工作簿。选择现有文件没有问题。但是,一旦我为新 Excel 文件创建名称,就会收到一条错误消息,提示“您的文件似乎不是有效的 OLE2 文档”。
public void selectExcelFile() {
String excelFileName = null; // the name/directory/address of the excel file created/selected
FileInputStream excelFileIn = null; // allows us to connect to the Excel file so we can read it
FileOutputStream excelFileOut = null; // allows us to connect to the Excel file so we can write to it
ExcelFileUtility eUtil = new ExcelFileUtility(); // used open an excel file
if(columnsQuery != null) {
try {
excelFileName = eUtil.getFile(FileExtensions.XLS); // file extension = ".xls"
if(excelFileName != null) {
excelFileIn = new FileInputStream(new File(excelFileName));
workbook = new HSSFWorkbook(excelFileIn);
exportColsToWorkbook(columnsQuery);
excelFileOut = new FileOutputStream(excelFileName);
workbook.write(excelFileOut);
// close everything
workbook.close();
excelFileIn.close();
excelFileOut.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
And then:
进而:
public String getFile(String extension) {
String result = null;
if(extension != null) {
int choice = askIfNewFile();
if(choice == 0) { // yes, create new file
result = createFile(extension);
}
else { // no, select existing file
result = getFileLocation();
}
}
else {
System.out.println("No file extension.");
}
return result;
}
public String createFile(String extension) throws IOException {
String newFileName = "";
File newFile = null;
boolean isCreated = false;
JFrame frame = new JFrame("Creating a New ." + extension + " File");
String result = null;
String dir = getFileDirectory();
System.out.println("DIR: " + dir);
if(dir != null) {
while(newFileName.isEmpty() || newFileName == null) {
// Used WorkbookUtil.createSafeSheetName to validate file name
// Please replace if there is a better option
newFileName = WorkbookUtil.createSafeSheetName(JOptionPane.showInputDialog(frame, "Enter new ." + extension + " file name:"));
}
newFile = new File(dir + "\" + newFileName + "." + extension);
System.out.println(newFile.toString());
try {
isCreated = newFile.createNewFile();
if(isCreated) {
result = newFile.getAbsolutePath();
}
else {
System.out.println("File already exists.");
}
}
catch(IOException ioe) {
System.out.println(ioe);
}
}
return result;
}
public String getFileLocation() {
String result = null;
JFileChooser pickFile = new JFileChooser();
if (pickFile.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
try {
result = pickFile.getSelectedFile().getCanonicalPath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// check if file exists
}
System.out.println("File location: " + result);
return result;
}
public String getFileDirectory() {
String result = null;
JFileChooser pickFile = new JFileChooser();
pickFile.setDialogTitle("Choose Folder");
pickFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
pickFile.setAcceptAllFileFilterUsed(false);
if (pickFile.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
result = pickFile.getSelectedFile().toString();
}
else {
System.out.println("No Selection ");
}
return result;
}
Here is the error I get:
这是我得到的错误:
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:162)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:112)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:300)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:400)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:381)
at mhhls.him.dbtoexcel.program.DBtoExcel.selectExcelFile(DBtoExcel.java:159)
at mhhls.him.dbtoexcel.program.DBtoExcel.exportToExcel(DBtoExcel.java:422)
at mhhls.him.dbtoexcel.ui.main.DBtoExcelWindow.actionPerformed(DBtoExcelWindow.java:183)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
EDITED: I changed the selectExcelFile() method into this:
编辑:我将 selectExcelFile() 方法更改为:
public void selectExcelFile() {
String excelFileName = null; // the name/directory/address of the excel file created/selected
FileInputStream excelFileIn = null; // allows us to connect to the Excel file so we can read it
FileOutputStream excelFileOut = null; // allows us to connect to the Excel file so we can write to it
ExcelFileUtility eUtil = new ExcelFileUtility(); // used open an excel file
File newFile = null;
if(columnsQuery != null) {
try {
excelFileName = eUtil.getFile(FileExtensions.XLS);
if(excelFileName != null) {
newFile = new File(excelFileName);
if(newFile.exists()) {
try {
workbook = WorkbookFactory.create(newFile);
} catch (EncryptedDocumentException | InvalidFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
if (newFile.getName().endsWith(".xls")) {
workbook = new HSSFWorkbook();
}
else if (newFile.getName().endsWith(".xlsx")) {
workbook = new XSSFWorkbook();
}
else {
throw new IllegalArgumentException("Must be .xls or .xlsx");
}
}
excelFileIn = new FileInputStream(newFile);
exportColsToWorkbook(columnsQuery);
excelFileOut = new FileOutputStream(newFile);
workbook.write(excelFileOut);
// close everything
workbook.close();
excelFileIn.close();
excelFileOut.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
Writing the workbook on the Excel file worksheet supposedly worked (did not get any errors), but when I opened the Excel file to check, I suddenly get this:
在 Excel 文件工作表上编写工作簿应该有效(没有出现任何错误),但是当我打开 Excel 文件进行检查时,我突然得到了这个:
I click ok, and it's just empty. No worksheets or workbook.
我点击确定,它只是空的。没有工作表或工作簿。
So that explains why I get this error the next time I run the program and try to write the workbook on the same Excel file.
这解释了为什么我下次运行程序并尝试在同一个 Excel 文件上编写工作簿时出现此错误。
Exception in thread "AWT-EventQueue-0" org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:216)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:166)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:278)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:250)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:229)
at mhhls.him.dbtoexcel.program.DBtoExcel.selectExcelFile(DBtoExcel.java:205)
at mhhls.him.dbtoexcel.program.DBtoExcel.exportToExcel(DBtoExcel.java:487)
at mhhls.him.dbtoexcel.ui.main.DBtoExcelWindow.actionPerformed(DBtoExcelWindow.java:190)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
I just don't understand why it corrupts the Excel file whenever I try to write the workbook onto a new worksheet.
我只是不明白为什么每当我尝试将工作簿写入新工作表时它会损坏 Excel 文件。
采纳答案by Gagravarr
You seem to have missed some key lines of code. However, assuming you are currently doing something like:
您似乎错过了一些关键的代码行。但是,假设您目前正在执行以下操作:
File newFile = new File("output.xlsx");
if (!newFile.exists) { newFile.createNewFile(); }
Workbook wb = WorkbookFactory.create(newFile);
Then this will not work!
那么这行不通!
You may only use WorkbookFactory
to load pre-existing Excel files. You cannotuse WorkbookFactory
to create a brand new, empty Workbook. Very much related, you also can't do new HSSFWorkbook(emptyStream)
or new HSSFWorkbook(emptyFile)
, if creating a *SSFWorkbook
from an InputStream
or a File
then that must exist and be populated.
您只能用于WorkbookFactory
加载预先存在的 Excel 文件。您不能用于WorkbookFactory
创建全新的空工作簿。非常相关,您也不能执行new HSSFWorkbook(emptyStream)
or new HSSFWorkbook(emptyFile)
,如果*SSFWorkbook
从 anInputStream
或 a创建aFile
那么必须存在并填充。
Instead, if you want to create a brand new empty workbook, what you need to do is more like:
相反,如果您想创建一个全新的空工作簿,您需要做的更像是:
Workbook wb;
File newFile = new File("output.xlsx");
if (newFile.exists) {
// Load existing
wb = WorkbookFactory.create(newFile);
} else {
// What kind of file are they trying to ask for?
// Add additional supported types here
if (newFile.getName().endsWith(".xls")) {
wb = new HSSFWorkbook();
}
else if (newFile.getName().endsWith(".xlsx")) {
wb = new XSSFWorkbook();
}
else {
throw new IllegalArgumentException("I don't know how to create that kind of new file");
}
}
For brand new empty files, you need to decide what kind of file to create, then new the appropriate *SSFWorkbook
instance for it with no stream/file passed in
对于全新的空文件,您需要决定要创建的文件类型,然后为其新建适当的*SSFWorkbook
实例,不传入流/文件