如何找出导致 poi 损坏 xlsx / xlsm 文件的原因
How to find out what makes poi corrupt a xlsx / xlsm file
我遇到的问题是 Apache POI "corrupted" 一个 xlsm / xlsx 文件,只需读写它(例如使用以下代码)
public class Snippet {
public static void main(String[] args) throws Exception {
String str1 = "c:/tmp/spreadsheet.xlsm";
String str2 = "c:/tmp/spreadsheet_poi.xlsm";
// open file
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(new File(str1)));
// save file
FileOutputStream out = new FileOutputStream(str2);
wb.write(out);
wb.close();
out.close();
}
}
在 Excel 中打开 spreadsheet_poi.xlsm 后,您将收到如下错误
"We found a problem with some content in xxx. Do you want us to try to recover as much as we can..."?
如果您同意,您最终会得到一个如下所示的日志:
<?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>
更详细地调试问题的最佳方法是什么(例如找出是什么使 poi 成为 "corrupt" 文件?
最终我发现调试的最佳方法是两件事
- 打开受影响的工作簿(例如使用 7zip 并使用 xml 编辑器格式化受影响的 sheets(例如 Notepad++ > Plugins > XML Tools > Pretty print (XML only - with line breaks)。保存文件并更新 xlsm 文件后,您将在 Excel 错误日志中获得 "real" 行号。替代选项(我没有尝试过但是应该根据 POI 邮件列表工作:使用
OOXMLPrettyPrint
(https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/dev/) 格式化文件,然后在 excel. 中重新打开它
- 如果实际行号还没有帮助比较原始 xlsx 文件的 sheet xml 文件和 poi 保存的文件。您会注意到在属性方面存在差异,而且顺序也不同。为了正确比较,我使用了 Beyond Compare 和 "Additional File Formats"(有关更多信息,请参阅 https://weblogs.asp.net/lorenh/comparing-xml-files-with-beyond-compare-3-brilliant)。也许还有另一个同样出色的 diff 工具。
在我的例子中,问题是 poi 以某种方式改变了尺寸设置
<dimension ref="A1:XFD147"/>
到
<dimension ref="A1:XFE147"/>
(XFE 是一个不存在的列)。我通过删除原始 xlsx 文件中的许多空列来修复它。
我的教授说:"How does the mathematician find the lion in the desert?" - "First cuts the desert into two halves, finds out where is the lion, then repeats it until the lion is caught"。
所以,尝试从 Excel 文件中删除功能,尝试不同的版本,直到找到根本原因。不过,可能有多种原因。
我遇到的问题是 Apache POI "corrupted" 一个 xlsm / xlsx 文件,只需读写它(例如使用以下代码)
public class Snippet {
public static void main(String[] args) throws Exception {
String str1 = "c:/tmp/spreadsheet.xlsm";
String str2 = "c:/tmp/spreadsheet_poi.xlsm";
// open file
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(new File(str1)));
// save file
FileOutputStream out = new FileOutputStream(str2);
wb.write(out);
wb.close();
out.close();
}
}
在 Excel 中打开 spreadsheet_poi.xlsm 后,您将收到如下错误
"We found a problem with some content in xxx. Do you want us to try to recover as much as we can..."?
如果您同意,您最终会得到一个如下所示的日志:
<?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>
更详细地调试问题的最佳方法是什么(例如找出是什么使 poi 成为 "corrupt" 文件?
最终我发现调试的最佳方法是两件事
- 打开受影响的工作簿(例如使用 7zip 并使用 xml 编辑器格式化受影响的 sheets(例如 Notepad++ > Plugins > XML Tools > Pretty print (XML only - with line breaks)。保存文件并更新 xlsm 文件后,您将在 Excel 错误日志中获得 "real" 行号。替代选项(我没有尝试过但是应该根据 POI 邮件列表工作:使用
OOXMLPrettyPrint
(https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/dev/) 格式化文件,然后在 excel. 中重新打开它
- 如果实际行号还没有帮助比较原始 xlsx 文件的 sheet xml 文件和 poi 保存的文件。您会注意到在属性方面存在差异,而且顺序也不同。为了正确比较,我使用了 Beyond Compare 和 "Additional File Formats"(有关更多信息,请参阅 https://weblogs.asp.net/lorenh/comparing-xml-files-with-beyond-compare-3-brilliant)。也许还有另一个同样出色的 diff 工具。
在我的例子中,问题是 poi 以某种方式改变了尺寸设置
<dimension ref="A1:XFD147"/>
到
<dimension ref="A1:XFE147"/>
(XFE 是一个不存在的列)。我通过删除原始 xlsx 文件中的许多空列来修复它。
我的教授说:"How does the mathematician find the lion in the desert?" - "First cuts the desert into two halves, finds out where is the lion, then repeats it until the lion is caught"。
所以,尝试从 Excel 文件中删除功能,尝试不同的版本,直到找到根本原因。不过,可能有多种原因。