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

2024-03-17 02:52

本文主要是介绍【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;}}}

这篇关于【Poi-tl Documentation】自定义占位符来设置图片大小的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

如何Python使用设置word的页边距

《如何Python使用设置word的页边距》在编写或处理Word文档的过程中,页边距是一个不可忽视的排版要素,本文将介绍如何使用Python设置Word文档中各个节的页边距,需要的可以参考下... 目录操作步骤代码示例页边距单位说明应用场景与高级用China编程途小结在编写或处理Word文档的过程中,页边距是一个

POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能

《POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能》ApachePOI是一个流行的Java库,用于处理MicrosoftOffice格式文件,提供丰富API来创建、读取和修改O... 目录前言:Apache POIEasyPoiEasyExcel一、EasyExcel1.1、核心特性

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定