背景
业务需要从url中下载到文件(都是excel),解析文件内容后,对于解析有问题的记录在最后一列写上问题原因,并提供下载链接,下载后文件需要有用户水印。
流程图:
问题
在文件后续处理后(添加水印,写入错误信息等),生成新的excel文件用wps可以正常打开,用office打开却提示文件已损坏。
排查过程
1.使用无水印源文件进行上传,下载后带水印打开正常
2.使用有水印源文件进行上传,下载后office提示已损坏
通过对比得出本身带水印的文件再次添加水印后会出现问题。
写入水印的代码:
public static void putWaterRemarkToWorkBook(XSSFWorkbook workbook, byte[] bytes) {
//add relation from sheet to the picture data
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx);
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
//获取每个Sheet表
XSSFSheet sheet = workbook.getSheetAt(i);
PackagePartName ppn = pictureData.getPackagePart().getPartName();
String relType = XSSFRelation.IMAGES.getRelation();
PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
}
}
通过debug调试观察:
源sheet中包含有Relationship水印图片记录,如果需要重新加水印,则需要清除以前的Relationship记录再添加新的。
poi sheet中没有提供方法去直接修改Relationship记录,只好再看其他的方法。
查看添加Relationship的源码,发现会根据id和type覆盖处理
修改代码进行尝试,找到id后直接进行添加Relationship
重启服务后,生成文件可正常打开。