如何确保 apache poi xwpf 中的 ctdocument 属性序列

MS office 在所有文档中生成此元素,并具有一些基本知识,即必须在一定程度上强制执行 NS 约束......


MS 文档示例:


<w:document

xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:o="urn:schemas-microsoft-com:office:office"

xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"

xmlns:v="urn:schemas-microsoft-com:vml"

xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"

xmlns:w10="urn:schemas-microsoft-com:office:word"

xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"

    <!--whatever-->

</w:document>

请注意 MC:IGNORABLE 元素已移动...手动修改 docx 存档中的此元素本身“修复”了 MSOffice 程序抛出的错误,该错误在第 2 行第 0 列中指定了一个错误。


到目前为止,我已经尝试过:


xwpfDocument.getDocument().getDomNode()

^ 已尝试以正确的顺序修改、删除和添加属性...不起作用,因为这种转变似乎发生在 XWPFDocument.write() 过程中的某处。


我还尝试从 docx 存档中提取 document.xml 文件,对其进行修改并将其注入回存档中……这似乎不起作用……CRC问题……


有没有办法访问 OPCPackage 或部分或任何东西以允许直接调用此元素中的内置“recalculateAttributesRelativeToNS”?


...或者作为替代方案..我如何在存档内的文档 xml 文件中自动更改 dom 并仍然确保 ms 兼容性?


[编辑:“XY”]


这种行为在以下场景中很明显:


fis = new FileInputStream(new File(path));

XWPFPicture picture = imageRun.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG, path, Units.toEMU(450), Units.toEMU(290));

文档打开正常。问题不存在。


添加这一行(我知道它在技术上不正确,但是不应该在第 2 行第 0 列报告错误,因为它应该在 xml 的下方进一步报告)搞砸了一切。


picture.getCTPicture().getSpPr().addNewEffectLst().addNewOuterShdw().setBlurRad(10000);

添加此行后,w:document 属性变为状态 2(poi 示例),从而触发 ms Office 的 MS 架构 NS 失效例程。


属性是正确的。顺序是错误的。手动将 mc:ignorable 属性移动到属性列表的末尾可以解决问题,并且文档加载没有问题。


这很可能是因为(在正确的实现中)xmlns:mc 属性在属性列表中的 mc:ignorable 属性之前,而在 poi 输出中它没有(mc:Ignorable 是列表中的第一个元素)。


牧羊人nacy
浏览 244回答 1
1回答

拉莫斯之舞

错误中第 2 行第 0 列的指向具有误导性。如果你看,/word/document.xml那么根本只有 2 行。第 1 行中的 XML 声明和第 2 行中的所有其他 XML。您的问题是架构定义CT_OuterShadowEffect是:<xsd:complexType name="CT_OuterShadowEffect">&nbsp;<xsd:sequence>&nbsp; <xsd:group ref="EG_ColorChoice" minOccurs="1" maxOccurs="1"/>&nbsp;</xsd:sequence>&nbsp;<xsd:attribute name="blurRad" type="ST_PositiveCoordinate" use="optional" default="0"/>&nbsp;<xsd:attribute name="dist" type="ST_PositiveCoordinate" use="optional" default="0"/>&nbsp;<xsd:attribute name="dir" type="ST_PositiveFixedAngle" use="optional" default="0"/>&nbsp;<xsd:attribute name="sx" type="ST_Percentage" use="optional" default="100%"/>&nbsp;<xsd:attribute name="sy" type="ST_Percentage" use="optional" default="100%"/>&nbsp;<xsd:attribute name="kx" type="ST_FixedAngle" use="optional" default="0"/>&nbsp;<xsd:attribute name="ky" type="ST_FixedAngle" use="optional" default="0"/>&nbsp;<xsd:attribute name="algn" type="ST_RectAlignment" use="optional" default="b"/>&nbsp;<xsd:attribute name="rotWithShape" type="xsd:boolean" use="optional" default="true"/></xsd:complexType>如您所见,EG_ColorChoice必须发生 1 次。换句话说: 必须有一个颜色设置CTOuterShadowEffect。以下代码对我有用:import java.io.FileOutputStream;import java.io.FileInputStream;import java.io.InputStream;import org.apache.poi.xwpf.usermodel.*;import org.apache.poi.util.Units;public class WordInsertPicturesWithShadow {&nbsp;public static void main(String[] args) throws Exception {&nbsp; XWPFDocument document = new XWPFDocument(new FileInputStream("source.docx"));&nbsp; XWPFParagraph paragraph = document.createParagraph();&nbsp; XWPFRun run = paragraph.createRun();&nbsp; run.setText("The picture: ");&nbsp; InputStream in = new FileInputStream("samplePict.jpeg");&nbsp; XWPFPicture picture = run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(100));&nbsp; in.close();&nbsp;&nbsp;&nbsp; picture.getCTPicture().getSpPr().addNewEffectLst().addNewOuterShdw().setBlurRad(50000);&nbsp; //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDist(100000);&nbsp; //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDir(2700000);&nbsp; //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setAlgn(&nbsp; // org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment.TL);&nbsp; //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setRotWithShape(false);&nbsp; picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().addNewPrstClr().setVal(&nbsp; &nbsp;org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal.BLACK);&nbsp; run.setText(" text after the picture.");&nbsp; paragraph = document.createParagraph();&nbsp; FileOutputStream out = new FileOutputStream("result.docx");&nbsp; document.write(out);&nbsp; out.close();&nbsp; document.close();&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java