java poi 将公文套红 并 电子签章

套红的方法

签章:

 

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.Units;
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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.springframework.core.io.ClassPathResource;

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

/**
 * @author 7788
 * @version 12.0
 * @date 2021/1/6 下午 3:38
 * @location wuhan
 * 文档地址
 * http://deepoove.com/poi-tl/apache-poi-guide.html#_文档xwpfdocument
 * http://deepoove.com/poi-tl/#_%E7%A4%BA%E4%BE%8B
 */
@Slf4j
public class PoiTlUtil {

    /** 
     * @param content  公文源文件地址
     * @param data     需要填写的参数
     * @param destDocx 保存的文件地址
     * @param fileName 设置的文件名称
     */
    public static void word2RedDocument(String content, Map<String, Object> data, String destDocx, String fileName) throws Exception {
        File file = new File(destDocx);
        if (!file.exists()) {
            file.mkdirs();
        }
        //红头文件模板
        InputStream resourceAsStream = new ClassPathResource("files/xingzheng.docx").getInputStream();  
        XWPFTemplate template = XWPFTemplate.compile(resourceAsStream).render(data);
        //获取模板
        NiceXWPFDocument main = template.getXWPFDocument();
        // 合并两个文档
        NiceXWPFDocument sub = new NiceXWPFDocument(new FileInputStream(content));
        // 生成新文档
        XWPFDocument newDoc = main.merge(sub);
        log.info(fileName + " 套红成功");

        //签章
        XWPFParagraph paragraph = null;
        //XWPFRun targetRun = null;
        List<XWPFParagraph> xwpfParagraphList = newDoc.getParagraphs();
        for (XWPFParagraph x : xwpfParagraphList) {
            String text = x.getText();
            if (text.contains("盖章")) {
                paragraph = x;
                break;
            }
        }
        if (paragraph != null) {
            //添加印章图片
            XWPFRun targetRun = paragraph.createRun();
            InputStream inputStream = new ClassPathResource("files/wutansign.jpeg").getInputStream();
            targetRun.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_JPEG, "sign", Units.toEMU(100), Units.toEMU(100));
            inputStream.close();
            log.info(fileName + " 盖章...");
            CTR targetRunCtr = targetRun.getCTR();
            if (targetRunCtr.sizeOfDrawingArray() > 0) {
                CTDrawing drawing = targetRunCtr.getDrawingArray(0);
                if (drawing.sizeOfInlineArray() > 0) {
                    CTGraphicalObject graphic = drawing.getInlineArray(0).getGraphic();
                    //log.info("graphic   " + graphic.toString());
                    //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
                    CTAnchor anchor = getAnchorWithGraphic(graphic, "Seal" + System.currentTimeMillis(),
                            Units.toEMU(100), Units.toEMU(100),
                            Units.toEMU(250), Units.toEMU(0), false);
                    //log.info("anchor   " + anchor.toString());
                    drawing.setAnchorArray(new CTAnchor[]{anchor});
                    drawing.removeInline(0);
                }
                //log.info("drawing   " + drawing.toString());
            }
        }
        //输出文件
        FileOutputStream out = new FileOutputStream(destDocx + fileName);
        newDoc.write(out);
        newDoc.close();
        out.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) {
        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;
    }
}

效果图
在这里插入图片描述

posted @ 2021-05-11 14:44  qwer78  阅读(863)  评论(0)    收藏  举报