更改图像布局或使用Apache POI包装在DOCX中 [英] Change image layout or wrap in DOCX with Apache POI
问题描述
我以编程方式将图像粘贴到docx中.但是结果是布局不适合我.面对文件不足的情况. 我需要更改图像换行(布局).例如,现在我有这个:
I paste image into docx programmatically. But in result the layout does not suit me. Faced a lack of documentation. I need to change image wrap (layout). For example now I have this:
但是想要这个:
UPD1 :我的工作:遍历各个段落,然后遍历各个运行,并使用特殊的书签查找特定的运行.在此运行中,我添加图片:
UPD1: What I do: iterate through the paragraphs, then through the runs and find certain run with special bookmark. In this run I add picture:
XWPFPicture pic = run.addPicture(
new ByteArrayInputStream(picSource),
Document.PICTURE_TYPE_PNG,
"pic",
Units.toEMU(100),
Units.toEMU(30));
UPD2 :研究了此类中的一些有趣内容:
UPD2: Investigated something interesting inside this class:
org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor
方法setWrapTight(CTWrapTight var1)
.可能是这样.仍然不知道如何将其应用于我的代码.
method setWrapTight(CTWrapTight var1)
. May be is it. By still don't know how to apply it to my code.
UPD3 :最后,我来到了这里(currentRun-运行我们的图片):
UPD3: Finally I came to this (currentRun - run with our picture):
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);
但是当我尝试打开它时,它会分解文档:
But it's break down document when I try to open it:
对不起.我们发现文档存在问题,因此无法打开文档 它的内容.
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>
推荐答案
虽然您已经找到了适合使用的类-锚点的XML模式定义.这表明,除了定义包装的职责元素以外,还需要更多的职责元素.因此,按类使用org.openxmlformats.schemas.drawingml.x2006
可能是在编写页面明智代码.对于此类问题,我的首选解决方案是提供XML
,其中所有必需的元素都由某些变量更新.然后可以解析此XML
以获得所需的对象.
While you already found the right classes to use - CTAnchor and successors - there is also the need considering the XML Schema definition of anchor. And this states there are many more duty elements required than only the ones which are defining wrapping. So using class by class of org.openxmlformats.schemas.drawingml.x2006
you are probably coding page wise code. My preferred solution for such problems is providing XML
having all needed elements updated by some variables. This XML
then can be parsed to get the needed object.
示例:
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();
}
}
这篇关于更改图像布局或使用Apache POI包装在DOCX中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!