java - 使用 Apache POI 更改图像布局或包装在 DOCX 中

标签 java apache-poi docx

我以编程方式将图像粘贴到 docx 中。但结果布局不适合我。面临缺乏文件。 我需要更改图像环绕(布局)。例如现在我有这个:

enter image description here

但是想要这个:

enter image description here

UPD1:我所做的:遍历段落,然后遍历运行并找到带有特殊书签的特定运行。在这次运行中,我添加了图片:

XWPFPicture pic =  run.addPicture(
        new ByteArrayInputStream(picSource),
        Document.PICTURE_TYPE_PNG,
        "pic",
        Units.toEMU(100),
        Units.toEMU(30));

UPD2:调查了这个类中的一些有趣的东西:

org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor

方法 setWrapTight(CTWrapTight var1)。可能是它。仍然不知道如何将它应用到我的代码中。

UPD3:我终于想到了这个(currentRun - 用我们的照片运行):

    CTWrapTight ctWrapTight = currentRun.getCTR().getDrawingList().get(0).addNewAnchor().addNewWrapTight();
 CTWrapPath ctWrapPath = ctWrapTight.addNewWrapPolygon();

 CTPoint2D ctStart = ctWrapPath.addNewStart();
 ctStart.setX(0L);
 ctStart.setY(0L);

 CTPoint2D ctLineTo1 = ctWrapPath.addNewLineTo();
 CTPoint2D ctLineTo2 = ctWrapPath.addNewLineTo();
 CTPoint2D ctLineTo3 = ctWrapPath.addNewLineTo();

 ctLineTo1.setX(21384L);
 ctLineTo1.setY(20520L);

 ctLineTo2.setX(21384L);
 ctLineTo2.setY(0L);

 ctLineTo3.setX(0L);
 ctLineTo3.setY(0L);

ctWrapTight.setWrapText(STWrapText.BOTH_SIDES);

但是当我尝试打开它时它是分解文档:

We're sorry. We can't open document because we found a problem with its contents.

依赖是:

<dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.3</version>
    </dependency>

最佳答案

虽然您已经找到要使用的正确类 - CTAnchor和继任者 - 还需要考虑 XML Schema definition of anchor .这说明需要的职责要素比定义包装的职责要素多得多。因此,逐个类地使用 org.openxmlformats.schemas.drawingml.x2006 您可能正在编写页面智能代码。对于此类问题,我的首选解决方案是提供 XML,其中所有需要的元素都由一些变量更新。然后可以解析此 XML 以获取所需的对象。

例子:

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.util.Units;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;

public class WordInsertPictures {

 private static CTAnchor getAnchorWithGraphic(CTGraphicalObject graphicalobject, 
                                              String drawingDescr, int width, int height,
                                              int left, int top) throws Exception {

  String anchorXML = 
   "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
  +"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"1\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
  +"<wp:simplePos x=\"0\" y=\"0\"/>"
  +"<wp:positionH relativeFrom=\"column\"><wp:posOffset>"+left+"</wp:posOffset></wp:positionH>"
  +"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>"+top+"</wp:posOffset></wp:positionV>"
  +"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"
  +"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
  +"<wp:wrapTight wrapText=\"bothSides\">"
  +"<wp:wrapPolygon edited=\"0\">"
  +"<wp:start x=\"0\" y=\"0\"/>"
  +"<wp:lineTo x=\"0\" y=\"21600\"/>" //Square polygon 21600 x 21600 leads to wrap points in fully width x height
  +"<wp:lineTo x=\"21600\" y=\"21600\"/>"// Why? I don't know. Try & error ;-).
  +"<wp:lineTo x=\"21600\" y=\"0\"/>"
  +"<wp:lineTo x=\"0\" y=\"0\"/>"
  +"</wp:wrapPolygon>"
  +"</wp:wrapTight>"
  +"<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"
  +"</wp:anchor>";

  CTDrawing drawing = CTDrawing.Factory.parse(anchorXML);
  CTAnchor anchor = drawing.getAnchorArray(0);
  anchor.setGraphic(graphicalobject);
  return anchor;  
 }

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

  XWPFDocument document = new XWPFDocument();
  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();

  run.setText("The picture in line: ");

  InputStream in = new FileInputStream("samplePict.jpeg");
  run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(30));
  in.close();  

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

  paragraph = document.createParagraph();

  run = paragraph.createRun();
  in = new FileInputStream("samplePict.jpeg");
  run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(30));
  in.close();  
  CTDrawing drawing = run.getCTR().getDrawingArray(0);
  CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
  CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "samplePict.jpeg", 
                                         Units.toEMU(100), Units.toEMU(30), 
                                         Units.toEMU(30), Units.toEMU(0));
  drawing.setAnchorArray(new CTAnchor[]{anchor});
  drawing.removeInline(0);

  run = paragraph.createRun();
  run.setText("The previous picture is anchored wrapTight. The previous picture is anchored wrapTight. The previous picture is anchored wrapTight. The previous picture is anchored wrapTight. The previous picture is anchored wrapTight. The previous picture is anchored wrapTight.");

  document.write(new FileOutputStream("WordInsertPictures.docx"));
  document.close();
 }
}

关于java - 使用 Apache POI 更改图像布局或包装在 DOCX 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47673133/

相关文章:

java - 使用 Apache POI hslf 调整图片大小/压缩图片 - PowerPoint

excel - 读取 XLSX 文件并将数据存储在 Grails 中的有效方法

python - 更改输入文件的路径,comtypes

c# - 使用 OpenXml 调用 AddAlternativeFormatImportPart 后文档损坏

docx - pandoc 跳过 latex 环境

java - 比较器的 NoSuchMethodError?

Java String.format args索引不一致

java - JBoss EAP 7.1 部署失败集成器 : Provider not found

java - 使用 jfreechart 在不同点之间创建 XY 图表

java - 如何使用 apache POI 在 docx 中插入当前日期字段