使用docx4j将XHTML转DOCX时图片未按100%宽度缩放的解决方法
解决docx4j转换XHTML时图片width:100%不生效的问题
方法一:配置XHTMLImporter基于页面实际宽度计算百分比
docx4j的XHTMLImporterImpl默认未关联文档页面宽度,导致百分比宽度无法正确转换。你需要先获取文档的页面可用宽度(页面宽度减去左右边距),传递给XHTMLImporter以计算图片实际尺寸。
修改代码如下:
String xhtmlText = addDoctype(pXHTML); WordprocessingMLPackage wordMLPackageXHTML = WordprocessingMLPackage.createPackage(); // 获取文档页面设置,计算可用宽度(单位:缇,1缇=1/20磅) SectionWrapper section = wordMLPackageXHTML.getMainDocumentPart().getSections().get(0); PageDimensions pageDimensions = section.getPageDimensions(); int pageWidth = pageDimensions.getWritableWidthTwips(); // 已减去边距的可用宽度 // 初始化XHTMLImporter并设置页面宽度参数 XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackageXHTML); xhtmlImporter.getCssWidthConverter().setPageWidth(pageWidth); wordMLPackageXHTML.getMainDocumentPart().getContent().addAll(xhtmlImporter.convert(xhtmlText, null)); Save saveToZip = new Save(wordMLPackageXHTML); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); saveToZip.save(byteArrayOutputStream);
方法二:手动拦截图片元素设置缩放比例
如果方法一不生效,可自定义XHTMLImporterImpl的图片处理逻辑,强制将图片缩放至页面可用宽度的100%:
String xhtmlText = addDoctype(pXHTML); WordprocessingMLPackage wordMLPackageXHTML = WordprocessingMLPackage.createPackage(); // 计算页面可用宽度 SectionWrapper section = wordMLPackageXHTML.getMainDocumentPart().getSections().get(0); PageDimensions pageDimensions = section.getPageDimensions(); int pageWidth = pageDimensions.getWritableWidthTwips(); XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackageXHTML) { @Override protected org.docx4j.wml.P processImageElement(org.jsoup.nodes.Element img, String src, String alt, String title) throws Exception { org.docx4j.wml.P p = super.processImageElement(img, src, alt, title); // 获取图片的Drawing和Inline对象 org.docx4j.wml.Drawing drawing = (org.docx4j.wml.Drawing)p.getContent().get(0); org.docx4j.dml.wordprocessingDrawing.Inline inline = (org.docx4j.dml.wordprocessingDrawing.Inline)drawing.getAnchorOrInline(); // 计算缩放比例 long originalWidth = inline.getExtent().getCx(); double scale = (double)pageWidth / originalWidth; // 设置图片新尺寸 inline.getExtent().setCx((long)(originalWidth * scale)); inline.getExtent().setCy((long)(inline.getExtent().getCy() * scale)); // 设置docx识别的缩放属性(以万分之一为单位) inline.getDocPr().setScaleX((int)(scale * 100000)); inline.getDocPr().setScaleY((int)(scale * 100000)); return p; } }; wordMLPackageXHTML.getMainDocumentPart().getContent().addAll(xhtmlImporter.convert(xhtmlText, null)); Save saveToZip = new Save(wordMLPackageXHTML); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); saveToZip.save(byteArrayOutputStream);
补充说明
- 缇(Twips)是DOCX的标准尺寸单位,1缇=1/20磅=1/1440英寸。
getWritableWidthTwips()已自动扣除左右边距,直接作为图片目标宽度即可。- 若文档有自定义页面大小或边距,需先设置好页面属性再计算可用宽度。
内容的提问来源于stack exchange,提问作者user26566721
相关产品推荐
相关产品推荐

