使用 Apache POI 更改图像布局或以 DOCX 换行

问题描述 投票:0回答:2

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

但是想要这个:

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);

但是当我尝试打开它时,它是崩溃的文档:

我们很抱歉。我们无法打开文档,因为我们发现有问题 它的内容。

依赖项是:

<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>
java apache-poi docx
2个回答
7
投票

虽然您已经找到了合适的类来使用 - CTAnchor 和后继者 - 还需要考虑锚点的 XML 模式定义。这表明需要更多的职责元素,而不仅仅是定义包装的元素。因此,使用 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(); } }
    

0
投票
如果你在C#中使用NPOI,你可以编写如下代码:

var imageRun = paragraph.CreateRun();

using (FileStream picData = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { imageRun.AddPicture(picData, (int)NPOI.XWPF.UserModel.PictureType.PNG, imagePath, Units.ToEMU(100), Units.ToEMU(100));

CT_Drawing drawing = imageRun.GetCTR().GetDrawingList().First(); CT_GraphicalObject graphicalobject = drawing.GetInlineArray(0).graphic; //Replace the newly inserted picture, add CTAnchor, set floating attribute, delete inline attribute CT_Anchor anchor = getAnchorWithGraphic(graphicalobject, "Seal", Units.ToEMU(120), Units.ToEMU(120), Units.ToEMU(50), Units.ToEMU(-80), true); drawing.anchor = new List<CT_Anchor>() { anchor };//Add floating attribute drawing.inline.RemoveAt(0);//R
}

静态 CT_Anchor GetAnchorWithGraphic(CT_GraphicalObject ctGraphicalObject, String deskFileName,int 宽度,int 高度, int leftOffset、int topOffset、bool 后面) {

String anchorXML = "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" " + "simplePos=\"0\" relativeHeight=\"1\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">" + "<wp:simplePos x=\"0\" y=\"0\"/>" + "<wp:positionH relativeFrom=\"page\">" + "<wp:posOffset>" + leftOffset + "</wp:posOffset>" + "</wp:positionH>" + "<wp:positionV relativeFrom=\"paragraph\">" + "<wp:posOffset>" + topOffset + "</wp:posOffset>" + "</wp:positionV>" + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>" + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" + "<wp:wrapNone/>" + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>" + "</wp:anchor>"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(anchorXML); CT_Drawing drawing = CT_Drawing.Parse(xmlDoc, XWPFPictureData.NamespaceManager); CT_Anchor anchor = drawing.GetAnchorList().First(); anchor.graphic = ctGraphicalObject; return anchor;
}

© www.soinside.com 2019 - 2024. All rights reserved.