首页 > 解决方案 > 使用 docx4j 库实现重新保存时 Excel 大小减小

问题描述

当我使用以下代码生成 excel 时,文件大小为 79kb。(步骤1)

如果我打开excel,什么都不做并保存。文件大小减小到 33kb。(第2步)

这可能是什么原因,我该如何避免这种情况?

提取 excel 后,我观察到drawing.xml 的大小变化。第 2 步 Xml 已格式化并具有前导和尾随空格。在第 1 步 xmls 被修剪的地方。

我已经使用 DOC4j 库来实现。

重新保存后文件大小减小。

`

public static void main(String[] args) throws IOException, Exception {

String outputfilepath =System.getProperty("user.dir") + "/sample-docs/outline5.xlsx";
String imagefilePath = "D:\\Checkout\\Images\\image.jpg" ;

SpreadsheetMLPackage pkg = SpreadsheetMLPackage.createPackage();
WorksheetPart worksheet = pkg.createWorksheetPart(new PartName("/xl/worksheets/sheet1.xml"), "Sheet1", 1);

// Create Drawing part and add to sheet
Drawing drawingPart = new Drawing();
Relationship drawingRel = worksheet.addTargetPart(drawingPart);

// Add anchor XML to worksheet
org.xlsx4j.sml.CTDrawing drawing = org.xlsx4j.jaxb.Context.getsmlObjectFactory().createCTDrawing();
worksheet.getJaxbElement().setDrawing(drawing);
drawing.setId( drawingRel.getId() );

// Create image part and add to Drawing part
BinaryPartAbstractImage imagePart
= BinaryPartAbstractImage.createImagePart(pkg, drawingPart,
FileUtils.readFileToByteArray(new File(imagefilePath) ));
String imageRelID = imagePart.getSourceRelationship().getId();

drawingPart.setJaxbElement(
buildDrawingPartContentFromXmlString(imageRelID));

// Save the xlsx
SaveToZipFile saver = new SaveToZipFile(pkg);
saver.save(outputfilepath);
System.out.println("\n\n done .. " + outputfilepath);
}

public static org.docx4j.dml.spreadsheetdrawing.CTDrawing buildDrawingPartContentFromXmlString(String imageRelID) throws JAXBException {

String openXML="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <xdr:wsDr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"> <xdr:twoCellAnchor editAs=\"oneCell\"> <xdr:from> <xdr:col>3</xdr:col> <xdr:colOff>0</xdr:colOff> <xdr:row>3</xdr:row> <xdr:rowOff>0</xdr:rowOff> </xdr:from> <xdr:to> <xdr:col>5</xdr:col> <xdr:colOff>104775</xdr:colOff> <xdr:row>7</xdr:row> <xdr:rowOff>142875</xdr:rowOff> </xdr:to> <xdr:pic> <xdr:nvPicPr> <xdr:cNvPr id=\"2\" name=\"Picture 1\"> <a:extLst> <a:ext uri=\"{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}\"> <a16:creationId xmlns:a16=\"http://schemas.microsoft.com/office/drawing/2014/main\" id=\"{00000000-0008-0000-0000-000002000000}\"/> </a:ext> </a:extLst> </xdr:cNvPr> <xdr:cNvPicPr> <a:picLocks noChangeAspect=\"1\"/> </xdr:cNvPicPr> </xdr:nvPicPr> <xdr:blipFill> <a:blip xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId1\" cstate=\"print\"> <a:extLst> <a:ext uri=\"{28A0092B-C50C-407E-A947-70E740481C1C}\"> <a14:useLocalDpi xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"0\"/> </a:ext> </a:extLst> </a:blip> <a:stretch> <a:fillRect/> </a:stretch> </xdr:blipFill> <xdr:spPr> <a:xfrm rot=\"18839999\"> <a:off x=\"0\" y=\"0\"/> <a:ext cx=\"714375\" cy=\"714375\"/> </a:xfrm> <a:prstGeom prst=\"rect\"> <a:avLst/> </a:prstGeom> </xdr:spPr> </xdr:pic> <xdr:clientData/> </xdr:twoCellAnchor> </xdr:wsDr>";
return (org.docx4j.dml.spreadsheetdrawing.CTDrawing)XmlUtils.unwrap(
XmlUtils.unmarshalString(openXML));
}

`

标签: excelxlsxdocx4j

解决方案


大概没什么好担心的。

一般来说,有 3 件事可以解释文件大小的差异:

  1. zip 实现的差异(Microsoft 与 Java)
  2. 命名空间
  3. mc:AlternateContent 处理

进一步查看https://www.docx4java.org/forums/docx-java-f6/file-size-differences-t1091.html


推荐阅读