POI 在Word中添加圖章--浮於文字或在文字下方的圖片(文字環繞)

1、添加依賴

<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>3.15</version>
</dependency>

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.15</version>
</dependency>

2、工具類

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Random;

public class WordSealUtil {
    public static void main(String[] args) throws Exception {
        sealInWord("D:\\test\\test.docx","D:\\test\\SealInWord.docx","D:\\test\\hh01.png","(簽字/蓋章)",0,0,300,-30,false);
    }
    /**
    * <b> Word中添加圖章
    * </b><br><br><i>Description</i> :
     * String srcPath, 源Word路徑
     * String storePath, 添加圖章後的路徑
     * String sealPath, 圖章路徑(即圖片)
     * tString abText, 在Word中蓋圖章的標識字符串,如:(簽字/蓋章)
     * int width, 圖章寬度
     * int height, 圖章高度
     * int leftOffset, 圖章在編輯段落向左偏移量
     * int topOffset, 圖章在編輯段落向上偏移量
     * boolean behind,圖章是否在文字下面
    * @return void
    * <br><br>Date: 2019/12/26 15:12     <br>Author : dxl
    */
    public static void sealInWord(String srcPath, String storePath,String sealPath,String tabText,
                                  int width, int height, int leftOffset, int topOffset, boolean behind) throws Exception {
        File fileTem = new File(srcPath);
        InputStream is = new FileInputStream(fileTem);
        XWPFDocument document = new XWPFDocument(is);
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        XWPFRun targetRun = null;
        for(XWPFParagraph  paragraph : paragraphs){
            if(!"".equals(paragraph.getText()) && paragraph.getText().contains(tabText)){
                List<XWPFRun> runs = paragraph.getRuns();
                targetRun = runs.get(runs.size()-1);
            }
        }
        if(targetRun != null){
            InputStream in = new FileInputStream(sealPath);//設置圖片路徑
            if(width <= 0){
                width = 100;
            }
            if(height <= 0){
                height = 100;
            }
            //創建Random類對象
            Random random = new Random();
            //產生隨機數
            int number = random.nextInt(999) + 1;
            targetRun.addPicture(in, Document.PICTURE_TYPE_PNG, "Seal"+number, Units.toEMU(width), Units.toEMU(height));
            in.close();
            // 2. 獲取到圖片數據
            CTDrawing drawing = targetRun.getCTR().getDrawingArray(0);
            CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();

            //拿到新插入的圖片替換添加CTAnchor 設置浮動屬性 刪除inline屬性
            CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "Seal"+number,
                    Units.toEMU(width), Units.toEMU(height),//圖片大小
                    Units.toEMU(leftOffset), Units.toEMU(topOffset), behind);//相對當前段落位置 需要計算段落已有內容的左偏移
            drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮動屬性
            drawing.removeInline(0);//刪除行內屬性
        }
        document.write(new FileOutputStream(storePath));
        document.close();
    }
    /**
     * @param ctGraphicalObject 圖片數據
     * @param deskFileName      圖片描述
     * @param width             寬
     * @param height            高
     * @param leftOffset        水平偏移 left
     * @param topOffset         垂直偏移 top
     * @param behind            文字上方,文字下方
     * @return
     * @throws Exception
     */
    public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                String deskFileName, int width, int height,
                                                int leftOffset, int topOffset, boolean behind) {
        System.out.println(">>width>>"+width+"; >>height>>>>"+height);
        String anchorXML =
                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<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>";

        CTDrawing drawing = null;
        try {
            drawing = CTDrawing.Factory.parse(anchorXML);
        } catch (XmlException e) {
            e.printStackTrace();
        }
        CTAnchor anchor = drawing.getAnchorArray(0);
        anchor.setGraphic(ctGraphicalObject);
        return anchor;
    }

}

 

發佈了64 篇原創文章 · 獲贊 6 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章