为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牧羊人nacy 2022-01-19 15:28:52
MS office 在所有文档中生成此元素,并具有一些基本知识,即必须在一定程度上强制执行 NS 约束......MS 文档示例:<w:documentxmlns: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 是列表中的第一个元素)。
查看完整描述

1 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

错误中第 2 行第 0 列的指向具有误导性。如果你看,/word/document.xml那么根本只有 2 行。第 1 行中的 XML 声明和第 2 行中的所有其他 XML。


您的问题是架构定义CT_OuterShadowEffect是:


<xsd:complexType name="CT_OuterShadowEffect">

 <xsd:sequence>

  <xsd:group ref="EG_ColorChoice" minOccurs="1" maxOccurs="1"/>

 </xsd:sequence>

 <xsd:attribute name="blurRad" type="ST_PositiveCoordinate" use="optional" default="0"/>

 <xsd:attribute name="dist" type="ST_PositiveCoordinate" use="optional" default="0"/>

 <xsd:attribute name="dir" type="ST_PositiveFixedAngle" use="optional" default="0"/>

 <xsd:attribute name="sx" type="ST_Percentage" use="optional" default="100%"/>

 <xsd:attribute name="sy" type="ST_Percentage" use="optional" default="100%"/>

 <xsd:attribute name="kx" type="ST_FixedAngle" use="optional" default="0"/>

 <xsd:attribute name="ky" type="ST_FixedAngle" use="optional" default="0"/>

 <xsd:attribute name="algn" type="ST_RectAlignment" use="optional" default="b"/>

 <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 {


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


  XWPFDocument document = new XWPFDocument(new FileInputStream("source.docx"));

  XWPFParagraph paragraph = document.createParagraph();

  XWPFRun run = paragraph.createRun();


  run.setText("The picture: ");


  InputStream in = new FileInputStream("samplePict.jpeg");

  XWPFPicture picture = run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(100));

  in.close();  


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

  //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDist(100000);

  //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDir(2700000);

  //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setAlgn(

  // org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment.TL);

  //picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setRotWithShape(false);

  picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().addNewPrstClr().setVal(

   org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal.BLACK);


  run.setText(" text after the picture.");


  paragraph = document.createParagraph();


  FileOutputStream out = new FileOutputStream("result.docx");

  document.write(out);

  out.close();

  document.close();

 }

}



查看完整回答
反对 回复 2022-01-19
  • 1 回答
  • 0 关注
  • 243 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信