项目背景 :公司的一个客户报告项目需要同步及抽取客户方的文件数据,文件类型为xls格式,文件为客户方的第三方厂商系统批量生成,工具及方法不明
问题 :读取该类xls文件后,无法成功创建Workbook,报错提示“Initialisation of record 0x203(NumberRecord) left 4 bytes remaining still to be read.”,该文件可通过Excel/WPS打开,并且重新保存后不会再次报错
工具库 :Apache POI -- 在C#中通过NPOI/EPPlus工具库测试同样报错
解决方案 :实际情况,大批量文件,让客户重新另存不现实,最终通过多方查询及讨论,通过应用LibreOffiec无头转换,将问题文件转换为xlsx格式后重新进行其余相关操作
具体解决方式 :
1. 下载安装对应系统的LibreOffice
2. 执行转换命令进行转换
2.1. 命令行方式
确保LibreOffice安装目录已成功添加到系统环境变量中,而后执行libreoffice --headless --convert-to xlsx /path/to/source.xls --outdir /path/to/output/ (Windows系统示例)
2.2. JAVA方式
public static void main(String[] args) {
String sourceFilePath = "/path/to/source.xls";
String targetFilePath = "/path/to/target.xlsx";
try {
Process process = Runtime.getRuntime().exec("libreoffice --headless --convert-to xlsx " + sourceFilePath + " --outdir " + targetFilePath);
process.waitFor();
System.out.println("File converted successfully.");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
2.3. C#方式
static void Main(string[] args) {
string sourceFilePath = "/path/to/source.xls";
string targetFilePath = "/path/to/target.xlsx";
try {
Process process = new Process();
process.StartInfo.FileName = "libreoffice";
process.StartInfo.Arguments = $"--headless --convert-to xlsx {sourceFilePath} --outdir {targetFilePath}";
process.Start();
process.WaitForExit();
Console.WriteLine("File converted successfully.");
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
3. 正常读取或写入转换后文件
备注 :
- 可转换源文件格式为xls即xls-->xls,但转换后仍存在初始错误,故而需转换为xlsx格式解决问题
- Apache POI提供xls转xlsx方式,但针对如上问题文件,在通过文件流创建workbook即WorkbookFactory.create(fis)已经报错,故而无法进行后续转换
- 针对初始报错,NPOI官方回复Resaving File解决问题,现实情况可能无法重存;网路可查询解决方案,为更新NPOI源码,在RecordInputStream处进行相应的代码变更,并规避掉后续的EOF异常,不推荐
- LibreOffice官网 - LibreOffice官网 NPOI GitHub Issue - Issue About