【Poi-tl Documentation】自定义占位符来设置图片大小

前置说明:

<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version>
</dependency>

模板文件:
image_test.docx

image.png

package run.siyuan.poi.tl.policy;import cn.hutool.core.util.ReUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.converter.ObjectToPictureRenderDataConverter;
import com.deepoove.poi.converter.ToRenderDataConverter;
import com.deepoove.poi.data.Paragraphs;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.style.PictureStyle;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.PictureRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.template.ElementTemplate;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.util.BufferedImageUtils;
import com.deepoove.poi.util.RegexUtils;
import com.deepoove.poi.util.SVGConvertor;
import com.deepoove.poi.util.UnitUtils;
import com.deepoove.poi.xwpf.BodyContainer;
import com.deepoove.poi.xwpf.BodyContainerFactory;
import com.deepoove.poi.xwpf.WidthScalePattern;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;/*** @ClassName CustomPictureRenderPolicy* @Description TODO* @Author siyuan* @Date 2024/3/3 12:53*/
public class CustomPictureRenderPolicy extends PictureRenderPolicy {public static void main(String[] args) throws IOException {// 读取模板文件FileInputStream fileInputStream = new FileInputStream("/Users/wuzhiqian/Desktop/HY/image_test.docx");// 创建模板配置ConfigureBuilder configureBuilder = Configure.builder();
//        configureBuilder.buildGrammerRegex(RegexUtils.createGeneral("{{", "}}"));
//        configureBuilder.buildGrammerRegex("((%)?[\\w\\u4e00-\\u9fa5]+(\\.[\\w\\u4e00-\\u9fa5]+)*(\\[\\d,\\d\\])?)?");configureBuilder.setValidErrorHandler(new Configure.DiscardHandler());configureBuilder.addPlugin('%', new CustomPictureRenderPolicy());// 创建模板上下文Map<String, Object> context = new HashMap<>();context.put("aaaa", Pictures.ofStream(Files.newInputStream(Paths.get("/Users/wuzhiqian/Desktop/HY/11111.png"))).create());context.put("name2", Pictures.ofStream(Files.newInputStream(Paths.get("/Users/wuzhiqian/Desktop/HY/11111.png"))).create());// 使用模板引擎替换文本标签XWPFTemplate compile = XWPFTemplate.compile(fileInputStream, configureBuilder.build());compile.render(context);// 保存生成的文档FileOutputStream outputStream = new FileOutputStream("/Users/wuzhiqian/Desktop/HY/image_test" + System.currentTimeMillis() + ".docx");compile.write(outputStream);outputStream.close();compile.close();fileInputStream.close();}private static ToRenderDataConverter<Object, PictureRenderData> converter = new ObjectToPictureRenderDataConverter();public CustomPictureRenderPolicy() {}public PictureRenderData cast(Object source) throws Exception {return (PictureRenderData)converter.convert(source);}protected boolean validate(PictureRenderData data) {return null != data;}protected void afterRender(RenderContext<PictureRenderData> context) {this.clearPlaceholder(context, false);}protected void reThrowException(RenderContext<PictureRenderData> context, Exception e) {this.logger.info("Render picture " + context.getEleTemplate() + " error: {}", e.getMessage());String alt = ((PictureRenderData)context.getData()).getAltMeta();context.getRun().setText(alt, 0);}public void beforeRender(RenderContext<PictureRenderData> context) {System.out.println("================");XWPFRun run = context.getRun();String source = context.getEleTemplate().getSource();String tagName = context.getEleTemplate().getTagName();System.out.println(source);Pattern pattern = Pattern.compile( "(.*)\\{\\{%"+tagName+"}}\\[\\d+,\\d+](.*)");XWPFParagraph parent = (XWPFParagraph) run.getParent();IBody body = parent.getBody();for (XWPFParagraph paragraph : body.getParagraphs()) {String text = paragraph.getText();System.out.println(text + "-------------------------------");if (text.contains(source) && ReUtil.isMatch(pattern,text) ) {String s = ReUtil.get("\\{\\{%"+tagName+"}}\\[\\d+,\\d+]", text, 0);System.out.println(s);s = ReUtil.get("\\[\\d+,\\d+]", s, 0);System.out.println(s);String[] split = s.replace("[", "").replace("]", "").split(",");Integer w = Integer.valueOf(split[0]);Integer h = Integer.valueOf(split[1]);PictureStyle pictureStyle = new PictureStyle();pictureStyle.setWidth(w);pictureStyle.setHeight(h);context.getData().setPictureStyle(pictureStyle);for (XWPFRun xwpfRun : paragraph.getRuns()) {if (s.equals(xwpfRun.text())){System.out.println(xwpfRun.text()+"   clean");// 删除[200,214] 格式字符BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(xwpfRun);bodyContainer.clearPlaceholder(xwpfRun);}}}}}public void doRender(RenderContext<PictureRenderData> context) throws Exception {CustomPictureRenderPolicy.Helper.renderPicture(context.getRun(), (PictureRenderData) context.getData());}public static class Helper {public Helper() {}public static void renderPicture(XWPFRun run, PictureRenderData picture) throws Exception {byte[] imageBytes = picture.readPictureData();if (null == imageBytes) {throw new IllegalStateException("Can't read picture byte arrays!");} else {// 根据图片流 设置图片类型PictureType pictureType = picture.getPictureType();if (null == pictureType) {pictureType = PictureType.suggestFileType(imageBytes);}// 图片类型为空,报错if (null == pictureType) {throw new RenderException("PictureRenderData must set picture type!");} else {PictureStyle style = picture.getPictureStyle();if (null == style) {style = new PictureStyle();}int width = style.getWidth();int height = style.getHeight();if (pictureType == PictureType.SVG) {imageBytes = SVGConvertor.toPng(imageBytes, (float) width, (float) height);pictureType = PictureType.PNG;}if (!isSetSize(style)) {BufferedImage original = BufferedImageUtils.readBufferedImage(imageBytes);width = original.getWidth();height = original.getHeight();if (style.getScalePattern() == WidthScalePattern.FIT) {BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run);int pageWidth = UnitUtils.twips2Pixel(bodyContainer.elementPageWidth((IBodyElement) run.getParent()));if (width > pageWidth) {double ratio = (double) pageWidth / (double) width;width = pageWidth;height = (int) ((double) height * ratio);}}}InputStream stream = new ByteArrayInputStream(imageBytes);try {PictureStyle.PictureAlign align = style.getAlign();if (null != align && run.getParent() instanceof XWPFParagraph) {((XWPFParagraph) run.getParent()).setAlignment(ParagraphAlignment.valueOf(align.ordinal() + 1));}run.addPicture(stream, pictureType.type(), "Generated", Units.pixelToEMU(width), Units.pixelToEMU(height));} catch (Throwable var13) {try {stream.close();} catch (Throwable var12) {var13.addSuppressed(var12);}throw var13;}stream.close();}}}private static boolean isSetSize(PictureStyle style) {return (style.getWidth() != 0 || style.getHeight() != 0) && style.getScalePattern() == WidthScalePattern.NONE;}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/543788.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Poi-tl Documentation】区块对标签显示隐藏改造

前置说明&#xff1a; <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version> </dependency>模板&#xff1a; 删除行表格测试.docx 改造前测试效果 package run.siyuan…

磁盘未格式化,数据恢复有妙招

一、初遇磁盘未格式化&#xff0c;惊慌失措 在日常生活和工作中&#xff0c;我们经常会使用各种存储设备来保存重要的文件和数据。然而&#xff0c;有时当我们尝试访问这些存储设备时&#xff0c;却会突然遇到一个令人头痛的问题——磁盘未格式化。这个突如其来的提示让我们措…

墨子web3时事周报

链上游戏平台Crypto Gladiator League推出全链游戏平台 链上游戏平台 Crypto Gladiator League&#xff08;CGL&#xff09;宣布重大升级&#xff0c;推出全链游戏平台&#xff0c;标志着其在区块链游戏领域的新突破。全新平台主要包括三大创新&#xff1a; 首先&#xff0c;推…

(每日持续更新)jdk api之StringBufferInputStream基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

《Python深度学习》阅读笔记

以下是《Python深度学习》一书中学习过程中记录的一些重要的专属名词和概念&#xff1a; 一、概念 深度学习&#xff08;Deep Learning&#xff09;&#xff1a;指使用多层神经网络进行机器学习的技术。神经网络&#xff08;Neural Network&#xff09;&#xff1a;一种模仿生…

『scrapy爬虫』05. 使用管道将数据写入mysql(详细注释步骤)

目录 1. 新建管道类,并启用2. 准备好mysql数据库新建表3. 实现管道写入数据库的代码测试一下 总结 欢迎关注 『scrapy爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『scrapy爬虫』 专栏&#xff0c;持续更新中 如果对mysql和python不熟悉可看专栏【Python之pymysql库学习】 1.…

移动云行动:5.5G技术引领数字化转型

刚刚结束的全国两会上&#xff0c;有人大代表建议应尽快发挥5G-A&#xff08;5.5G&#xff09;优势&#xff0c;加快试点城市布局。此前&#xff0c;中国移动已宣布将在300多个城市启动5.5G商用部署。在通信技术的历史长河中&#xff0c;4G改变了我们的生活方式&#xff0c;而5…

华为数通方向HCIP-DataCom H12-821题库(多选题:161-180)

第161题 以下关于IPv6优势的描述,正确的是哪些项? A、底层自身携带安全特性 B、加入了对自动配置地址的支持,能够无状态自动配置地址 C、路由表相比IPv4会更大,寻址更加精确 D、头部格式灵活,具有多个扩展头 【参考答案】ABD 【答案解析】 第162题 在OSPF视图下使用Filt…

强化学习------DDPG算法(附pytorch代码)

目录 一、前言二、基本原理2.1、经验回放2.2、更新过程2.2.1、Critic网络更新过程2.2.2、Actor网络更新过程2.2.3、 目标网络的更新 2.3、噪音探索 三、算法代码实现四、训练示例4.1、实现效果 一、前言 Deep Deterministic Policy Gradient (DDPG)算法是DeepMind团队提出的一…

浅谈性能测试中的基准测试

在性能测试中有一种测试类型叫做基准测试。这篇文章&#xff0c;就聊聊关于基准测试的一些事儿。 1、定义 通过设计合理的测试方法&#xff0c;选用合适的测试工具和被测系统&#xff0c;实现对某个特定目标场景的某项性能指标进行定量的和可对比的测试。 2、特质 ①、可重…

STL——map set

文章将解决一下几个问题&#xff1a; 1.什么是set 2.什么是map 3.set应用场景 4.map应用场景 序列式容器和关联式容器 数据结构有序列式容器和关联式容器&#xff0c;序列式容器一般有vector,list,deque…&#xff0c;但关联式容器中就有map&#xff0c;关联式容器也是用来存…

java基础-异常、常用类

异常 Exception 如果程序员认为一段代码可能出现异常/问题&#xff0c;try-catch异常处理机制来解决&#xff0c;从而保证程序的健壮性。将该代码块–》选中–》快捷键 ctrlaltt–》选中 try-catch 常见的一些异常~ 异常体系图&#xff0c;体现了继承和实现关系。&#xff08…