Java 如何找出poi损坏xlsx/xlsm文件的原因

Java 如何找出poi损坏xlsx/xlsm文件的原因,java,apache-poi,xlsx,xlsm,Java,Apache Poi,Xlsx,Xlsm,我有一个问题,Apache POI只是通过读取和写入一个xlsm/xlsx文件来“破坏”它(例如,使用以下代码) 在Excel中打开电子表格_poi.xlsm后,将出现如下错误 “我们发现xxx中的某些内容存在问题。是否希望我们尽可能多地恢复…” 如果您说是,您将得到一个日志,它可能如下所示: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <recoveryLog xmlns="http://schemas.op

我有一个问题,Apache POI只是通过读取和写入一个xlsm/xlsx文件来“破坏”它(例如,使用以下代码)

在Excel中打开电子表格_poi.xlsm后,将出现如下错误

“我们发现xxx中的某些内容存在问题。是否希望我们尽可能多地恢复…”

如果您说是,您将得到一个日志,它可能如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <logFileName>error145040_01.xml</logFileName>
    <summary>Errors were detected in file 'C:\tmp\spreadsheet_poi.xlsm'</summary>
    <repairedParts>
        <repairedPart>Repaired Part: /xl/worksheets/sheet4.xml part with XML error.  Load error. Line 2, column 0.</repairedPart>
        <repairedPart>Repaired Part: /xl/worksheets/sheet5.xml part with XML error.  Load error. Line 2, column 0.</repairedPart>
        <repairedPart>Repaired Part: /xl/worksheets/sheet8.xml part with XML error.  Load error. Line 2, column 0.</repairedPart>
    </repairedParts>
</recoveryLog>

error145040_01.xml
在文件“C:\tmp\spreadsheet\u poi.xlsm”中检测到错误
修复的零件:/xl/worksheets/sheet4.xml带有xml错误的零件。加载错误。第2行第0列。
修复的零件:/xl/worksheets/sheet5.xml带有xml错误的零件。加载错误。第2行第0列。
修复的零件:/xl/worksheets/sheet8.xml带有xml错误的零件。加载错误。第2行第0列。

更详细地调试该问题的最佳方法是什么(例如,找出是什么导致poi“损坏”文件?

最终我发现调试该问题的最佳方法是两件事

  • 打开受影响的工作簿(例如,使用7zip并使用xml编辑器格式化受影响的工作表(例如,记事本+++>插件>xml工具>漂亮打印(仅限xml-带换行符)。保存文件并更新xlsm文件后,您将在Excel错误日志中获得“真实”行号。可选选项(我没有尝试过,但应该根据POI邮件列表:使用
    ooxmlprepertyprint
    ()格式化文件,然后在excel中重新打开它
  • 如果实数行号还不能帮助比较原始xlsx文件和poi保存的图纸xml文件。您会注意到,在属性方面存在差异,而且顺序也不同。为了正确比较,我使用了Beyond compare和“其他文件格式”(有关更多信息,请参阅).也许还有另一个同样好的diff工具
  • 在我的例子中,问题是poi以某种方式更改了维度设置

    <dimension ref="A1:XFD147"/>
    
    
    

    
    

    (XFE是一个不存在的列)。我通过删除原始xlsx文件中的许多空列来修复它。

    最终我发现调试它的最佳方法是两件事

  • 打开受影响的工作簿(例如,使用7zip并使用xml编辑器格式化受影响的工作表(例如,记事本+++>插件>xml工具>漂亮打印(仅限xml-带换行符)。保存文件并更新xlsm文件后,您将在Excel错误日志中获得“真实”行号。可选选项(我没有尝试过,但应该根据POI邮件列表:使用
    ooxmlprepertyprint
    ()格式化文件,然后在excel中重新打开它
  • 如果实数行号还不能帮助比较原始xlsx文件和poi保存的图纸xml文件。您会注意到,在属性方面存在差异,而且顺序也不同。为了正确比较,我使用了Beyond compare和“其他文件格式”(有关更多信息,请参阅).也许还有另一个同样好的diff工具
  • 在我的例子中,问题是poi以某种方式更改了维度设置

    <dimension ref="A1:XFD147"/>
    
    
    

    
    
    (XFE是一个不存在的列)。我通过删除原始xlsx文件中的许多空列来修复它。

    我的教授说:“数学家如何在沙漠中找到狮子?”——“首先将沙漠切成两半,找出狮子在哪里,然后重复它,直到狮子被抓住”

    因此,尝试从Excel文件中删除功能,尝试不同的版本,直到找到根本原因。但可能有多种原因。

    我的教授说:“数学家如何在沙漠中找到狮子?”——“首先将沙漠切成两半,找出狮子在哪里,然后重复,直到狮子被抓住为止。”


    因此,请尝试从Excel文件中删除功能,尝试不同的版本,直到找到根本原因。但可能有多个原因。

    我也遇到过类似的问题,在创建
    文件输出流
    并写入工作簿之前,显式关闭
    文件输入流
    ,解决了这个问题。感谢您的建议这对我的情况没有帮助。我在下面概述了解决方案。我只是想提出这个问题,以便记录调试它的步骤(因为发生这种情况可能有各种原因)。最近我们遇到了问题,因为名称管理器引用了不再存在的文件。
    apache poi
    需要库来创建
    XML
    。我怀疑,由于某种程度上覆盖了默认值,因此使用了其他默认库来创建XML。例如,请参阅。我遇到了类似的问题,并得到了解决在创建
    FileOutputStream
    并写入工作簿之前,请明确关闭
    FileInputStream
    。感谢您的建议,但这对我的情况没有帮助。我在下面概述了解决方案。我只是想提出这个问题,以便记录调试它的步骤(原因可能多种多样)。最近我们遇到了问题,因为名称管理器引用了不再存在的文件。
    apache poi
    需要库来创建
    XML
    。我怀疑,由于某种程度上覆盖了默认值,因此使用了其他默认库来创建XML。例如,请参阅。
    <dimension ref="A1:XFE147"/>