【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

相关文章

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

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

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

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

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

PyCharm如何设置新建文件默认为LF换行符

《PyCharm如何设置新建文件默认为LF换行符》:本文主要介绍PyCharm如何设置新建文件默认为LF换行符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm设置新建文件默认为LF换行符设置换行符修改换行符总结PyCharm设置新建文件默认为LF

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT

Java利用poi实现word表格转excel

《Java利用poi实现word表格转excel》这篇文章主要为大家详细介绍了Java如何利用poi实现word表格转excel,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、每行对象类需要针对不同的表格进行对应的创建。package org.example.wordToEx

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth