Java poi读取xls文件出现nvalid header signature异常

来源:互联网 发布:java时间转换成毫秒 编辑:程序博客网 时间:2024/05/01 18:35

异常:

Invalid header signature; read0x0010000200040009, expected 0xE11AB1A1E011CFD0 - Your file appears not to be avalid OLE2 document

 

用Java poi(版本3.14)读取xls文件的时候出现这个异常,这是因为xls文件由第三方工具导出不是标准的Excel文件,网上说的打开另存的确可以解决问题,从文件大小就可以看到xls文件变大了。但是这个方法并不能解决我的问题,首先xls文件很多而且是要定期处理,我不能让使用程序的用户去手动另存吧!网上说了很多办法都解决不了我的问题,我也尝试了很多办法想通过Java来处理。最终实在没办法了,就想到通过VBA来处理,虽然这办法很糟糕而且只用于windows,但目前我也只能用这个办法了。

 

例如:用init.xls来自动加载宏

首先打开init.xls找到VB编辑器,粘贴下面代码,其中"C:\ProgramFiles\Test\"就是xls文件所在路径。

 

Private Sub Workbook_Open()

Dim mPath As String, fAAs String, wb As Workbook

On Error Resume Next

Application.ScreenUpdating= False

'----------设置文件夹路径-----

mPath = "C:\ProgramFiles\Test\"

'----------遍历目录--------

Application.DisplayAlerts= False

    fA = Dir(mPath & "*.xls")

    Do While fA <> ""

        If fA <> ThisWorkbook.Name Then

        Set wb = Workbooks.Open(mPath & fA,False) '打开

        wb.Save '保存

        wb.Close True '关闭工作薄

        End If

    fA = Dir

    Loop

Application.ScreenUpdating= True

Application.Quit    '退出Excel

End Sub

 

通过下面语句,在Java程序里这样就能打开init.xls,自动加载宏

Process process = Runtime.getRuntime().exec("cmd start /c init.xls");//如果是绝对路径要注意是否有空格,最好都加上""

process.waitFor();// 等到由该 Process 对象表示的进程已经终止 

缺点:

1.如果量大执行速度会慢点

2.每次都会弹出excel程序窗口,只有执行完宏才会自动关闭

3.如果此时还有其他工作薄打开的话也会被一起关闭,因为我VBA不熟所以只能一起处理了

4.还有最重要的一点就是宏安全性,如果禁止宏这些都不起作用了

 

为了解决如果用户禁用宏的情况,可以通过下面办法来调用init.xls文宏的Workbook_Open方法。虽然比Runtime.getRuntime().exec("cmd start /c init.xls")复杂很多,但是这样就能无视宏安全性设置了,不管是否禁用宏,都能调用Excel宏的Workbook_Open方法。

首先把jacob全部jar包导入到项目中,然后把dll文件复制到当前工作目录下。

下载链接:http://pan.baidu.com/s/1mhJZWuO   (如果链接失效也可以百度搜索下jacob-1.18)

  try {
                    ComThread.InitSTA();
                } catch (Error e) {                    

  //32位和64位操作系统分别对应jacob-1.18-x86.dll 、 jacob-1.18-x64.dll
                    JOptionPane.showMessageDialog(null, "jacob-1.18-" + System.getProperty("os.arch") + ".dll文件丢失或者损坏", "警告", JOptionPane.ERROR_MESSAGE);
                    e.printStackTrace();
                    System.exit(DO_NOTHING_ON_CLOSE);
                }

                ActiveXComponent xl = new ActiveXComponent("Excel.Application");
                try {
                    Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();    

//打开工作目录下的init.xls文件               
                    Dispatch excel = Dispatch.call(workbooks, "Open", System.getProperty("user.dir") + "/init.xls").toDispatch();
                    excel = null;
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 始终释放资源
                    xl.invoke("Quit", new Variant[]{});
                    xl = null;
                    ComThread.Release();
                }


为了解决这个问题花费了我很多时间,希望能帮上遇到同样问题的人。

 

 

1 0