poi-tl导出word实现图片环绕方式为浮于在文字上方办法

news/2024/11/26 9:40:21/

poi-tl导出word实现图片环绕方式为浮于在文字上方办法

  • poi-tl简介
    • 因为poi-tl暂时不支持设置图片环绕方式,但是可以自定义图片渲染插件

poi-tl简介

poi-tl(poi template language)是Word模板引擎,基于Microsoft Word模板和数据生成新的文档。
文档地址:http://deepoove.com/poi-tl/1.7.x/

因为poi-tl暂时不支持设置图片环绕方式,但是可以自定义图片渲染插件

废话少说,直接上代码

首先自定义一个图片渲染插件


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.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.util.BufferedImageUtils;
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 com.deepoove.poi.xwpf.XWPFRunWrapper;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
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 java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.function.Supplier;/*** 自定义图片渲染*/
public class MyPictureRenderPolicy extends AbstractRenderPolicy<Object> {@Overrideprotected boolean validate(Object data) {if (null == data) {return false;} else if (data instanceof PictureRenderData) {return null != ((PictureRenderData) data).getPictureSupplier();} else {return true;}}@Overridepublic void doRender(RenderContext<Object> context) throws Exception {MyPictureRenderPolicy.Helper.renderPicture(context.getRun(), wrapper(context.getData()));}@Overrideprotected void afterRender(RenderContext<Object> context) {this.clearPlaceholder(context, false);}@Overrideprotected void reThrowException(RenderContext<Object> context, Exception e) {this.logger.info("Render picture " + context.getEleTemplate() + " error: {}", e.getMessage());String alt = "";if (context.getData() instanceof PictureRenderData) {alt = ((PictureRenderData) context.getData()).getAltMeta();}context.getRun().setText(alt, 0);}private static PictureRenderData wrapper(Object object) {return object instanceof PictureRenderData ? (PictureRenderData) object : Pictures.of(object.toString()).fitSize().create();}public static class Helper {public static void renderPicture(XWPFRun run, PictureRenderData picture) throws Exception {Supplier<byte[]> supplier = picture.getPictureSupplier();byte[] imageBytes = (byte[]) supplier.get();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(((IBodyElement) run.getParent()).getBody());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);Throwable var25 = null;try {PictureStyle.PictureAlign align = style.getAlign();if (null != align && run.getParent() instanceof XWPFParagraph) {((XWPFParagraph) run.getParent()).setAlignment(ParagraphAlignment.valueOf(align.ordinal() + 1));}XWPFRunWrapper wrapper = new XWPFRunWrapper(run, false);wrapper.addPicture(stream, pictureType.type(), "Generated", Units.pixelToEMU(width), Units.pixelToEMU(height));CTDrawing drawing = run.getCTR().getDrawingArray(0);CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();//拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性CTAnchor anchor = ExportUtil.getAnchorWithGraphic(graphicalobject, "Generated",Units.toEMU(width), Units.toEMU(height),//图片大小Units.toEMU(270), Units.toEMU(-70), false);//相对当前段落位置 需要计算段落已有内容的左偏移drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性drawing.removeInline(0);//删除行内属性} catch (Throwable var20) {var25 = var20;throw var20;} finally {if (stream != null) {if (var25 != null) {try {stream.close();} catch (Throwable var19) {var25.addSuppressed(var19);}} else {stream.close();}}}}}}}private static boolean isSetSize(PictureStyle style) {return (style.getWidth() != 0 || style.getHeight() != 0) && style.getScalePattern() == WidthScalePattern.NONE;}}

浮于文字上方的核心代码提取出来放到了工具类里面

public class ExportUtil {/*** @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;}}

在使用poi-tl导出word时

ConfigureBuilder builder = Configure.builder();
builder.addPlugin('%',new MyPictureRenderPolicy());//把插件注册为新标签类型
XWPFTemplate template = XWPFTemplate.compile(templateIs,builder.build()).render(exportBO);

这样就能把模板里所有前缀为%的图片标签渲染为浮于文字上方


http://www.ppmy.cn/news/543467.html

相关文章

如何确定开关电源TL431反馈回路的参数

转载自《https://www.dianyuan.com/article/54404.html》 开关电源反馈回路主要由光耦&#xff08;如PC817&#xff09;、电压精密可调并联稳压器&#xff08;如TL431&#xff09;等器件组成。要研究如何设计反馈回路&#xff0c;首先先要了解这两个最主要元器件的基本参数。 一…

Redis 实战:逐步指南,让你轻松在 Linux 上安装与部署

目录 前言为什么会出现 Redis&#xff1f;磁盘、内存数据库缓存中间件 安装Redis5Redis6 使用总结 前言 Redis 中文网站&#xff1a;http://redis.cn/ Redis 是一个开源&#xff08;BSD 许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库…

XML系列篇之dtd约束

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于xml的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.XML 是什么 &#x1f4a1;辉辉小贴士&a…

电脑显示器突然变了颜色

显示器突然变了颜色 尝试插紧显示器的视频线并拧紧。

服务器内存插上显示器不亮,上两根内存条显示器就不亮了

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 两根内存条显示器不亮的解决方法&#xff1a; 1、先把旧的取下来&#xff0c;新的内存条插在刚才那个插槽&#xff0c;看看能不能正常点亮&#xff0c;如果能正常点亮&#xff0c;那…

计算机颜色偏蓝,电脑整个屏幕颜色不正常偏蓝怎么调回正常颜色?

想必很多用户在使用电脑过程中中会遇到一些问题。比如&#xff0c;有用户反映电脑整个屏幕的颜色都是不正常的颜色&#xff0c;整体出现偏蓝的现象。所以如何调整它&#xff1f;今天小编将给大家带来电脑屏幕颜色不正常偏蓝的详细调整方法。 电脑屏幕颜色调回正常具体步骤如下&…

服务器CRT显示不全,CRT显示器显示画面不正常常见原因揭密

画面偏移&#xff1a;有可能是旋钮失效或显示器水平震荡器已经损坏&#xff0c;水平震荡器通常处于显示器的光栅板上&#xff0c;请由专业人员更换。如果画面缩小&#xff0c;通常是器件老化的表现&#xff0c;也可能是显示器内部高压电路存在故障。也只能由专业人员处理。 画面…

计算机桌面颜色异常怎样修复,显示器颜色不正常如何调_电脑显示屏的颜色不对如何处理...

如果显示器的颜色不正常不对的话&#xff0c;长时间使用就会对我们的眼睛带来伤害&#xff0c;所以我们就需要对显示器颜色进行调整&#xff0c;但是仍然有一部分用户不知道显示器颜色不正常如何调&#xff0c;我们可以通过显示器颜色校正软件外&#xff0c;还能通过控制面板的…