package com.product.print.util; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.policy.AbstractRenderPolicy; import com.deepoove.poi.render.RenderContext; import com.deepoove.poi.xwpf.BodyContainer; import com.deepoove.poi.xwpf.BodyContainerFactory; import com.product.common.lang.StringUtils; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Base64; import java.util.Optional; /** * 自定义解析{{@var}}标签 * * @Author cheng * @Date 2023/6/27 15:50 * @Desc */ public class FlowOpinionRenderPolicy extends AbstractRenderPolicy { /** * 意见列表 */ private JSONArray opinionArray; public FlowOpinionRenderPolicy(JSONArray opinionArray) { this.opinionArray = opinionArray; } @Override public void doRender(RenderContext context) throws Exception { XWPFRun run = context.getRun(); //标签名称 String tagName = context.getEleTemplate().getTagName(); JSONObject opinion=null; //支持多个标签名称,用|分隔 例如:{{@var1|var2|var3...}} 按照顺序查找意见列表 for (String name : tagName.split("\\|")) { opinion = getOpinion(name); if(opinion!=null){ break; } } if (opinion == null) { //如果意见列表中没有找到,则直接替换为空 run.setText("", 0); return; } XWPFParagraph parent = (XWPFParagraph) run.getParent(); XWPFRun newRun = run; //判断是否有签名 if (!StringUtils.isEmpty(opinion.getString("sign_attachment_uuid"))) { XWPFParagraph paragraph = createParagraph(run); //设置签名的段落居右 paragraph.setAlignment(ParagraphAlignment.RIGHT); //插入一个新的run newRun = paragraph.createRun(); String signAttachmentBase64 = opinion.getString("sign_attachment_uuid"); String[] split = signAttachmentBase64.split(","); //将base64转换字节流 byte[] bytes = Base64.getDecoder().decode(split[split.length - 1]); //将字节流转为输入流 InputStream byteArrayInputStream = new ByteArrayInputStream(bytes); //插入图片 newRun.addPicture(byteArrayInputStream, XWPFDocument.PICTURE_TYPE_PNG, "sign.png", Units.toEMU(50), Units.toEMU(20)); byteArrayInputStream.close(); newRun.setText("", 0); } XWPFParagraph paragraph = createParagraph(newRun); //段落样式与原始段落一致 paragraph.getCTP().setPPr(parent.getCTP().getPPr()); //设置创建新的run XWPFRun textRun = paragraph.createRun(); //复制原始run PrintPoiUtil.copyRun(textRun, run); //设置run的内容 textRun.setText(Optional.ofNullable(opinion.getString("opinion")).orElse("未填写办理意见"), 0); //删除段落parent,如果只删除run,则会导致段落中还有一个空的run parent.getCTP().newCursor().removeXml(); } public XWPFParagraph createParagraph(XWPFRun run) { //获取body容器 BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run); //插入一个新的段落 XWPFParagraph paragraph = bodyContainer.insertNewParagraph(run); return paragraph; } public JSONObject getOpinion(String tagName) { //先用tagName去意见列表中查找node_uuid是否存在,不存在则使用node_title去查找 for (int i = 0; i < opinionArray.size(); i++) { JSONObject opinion = opinionArray.getJSONObject(i); if (tagName.equals(opinion.getString("node_uuid"))) { return opinion; } } for (int i = 0; i < opinionArray.size(); i++) { JSONObject opinion = opinionArray.getJSONObject(i); if (tagName.equals(opinion.getString("node_title"))) { return opinion; } } return null; } }