当前位置: 首页 > article >正文

Poi-tl实现图片自定义宽高、固定高度宽度自适应、固定宽度高度自适应

一、编写自定义插件CustomPictureRenderPolicy

CustomPictureRenderPolicy.java

package com.****public class CustomPictureRenderPolicy extends PictureRenderPolicy {

    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+"}}(.*)");
        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) ) {
                PictureStyle pictureStyle = new PictureStyle();
                // 读取图片宽高,固定高度,宽度等比例缩放
                byte[] bytes = context.getData().readPictureData();
                BufferedImage image = null;

                try {
                    // 将图片字节数据转换为 BufferedImage
                    InputStream inputStream = new ByteArrayInputStream(bytes);
                    image = ImageIO.read(inputStream);

                    // 获取图片的宽高
                    int originalWidth = image.getWidth();
                    int originalHeight = image.getHeight();

                    // 固定高度,例如设置为 200 像素
                    int fixedHeight = 150;

                    // 按比例计算新的宽度
                    int scaledWidth = (int) ((double) originalWidth / originalHeight * fixedHeight);

                    //System.out.println("原始宽度: " + originalWidth + ", 原始高度: " + originalHeight);
                    //System.out.println("新宽度: " + scaledWidth + ", 固定高度: " + fixedHeight);

                    pictureStyle.setWidth(scaledWidth);
                    pictureStyle.setHeight(fixedHeight);

                    // scaledBytes 可以用于后续处理,例如存储或传输
                } catch (IOException e) {
                    e.printStackTrace();
                }
                context.getData().setPictureStyle(pictureStyle);

            }
        }
    }

    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,1);
                        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;
        }
    }

}


二、word中标签

{{%imgUrl}}

三、调用

ConfigureBuilder builder = Configure.builder();

//图片的标签%
builder.addPlugin('%', new CustomPictureRenderPolicy());

注:第一步的插件实现的是固定高度等比缩放宽度,读者可以根据实际情况调整


http://www.kler.cn/a/464207.html

相关文章:

  • Git快速入门(三)·远程仓库GitHub以及Gitee的使用
  • 《Vue进阶教程》第三十四课:toRefs的使用
  • Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
  • 全国城市经纬度--包括省会(直辖市)、地级市
  • 基于Matlab的变压器仿真模型建模方法(12):单相降压自耦变压器的等效电路和仿真模型
  • Windows 11 系统中npm-cache优化
  • 【内含代码】Spring Boot整合深度学习框架DJL
  • 广西大数据局:数聚政府、利企惠民(广西数字政府建设内容、管理机制、应用场景)
  • gpt优化事件处理速度
  • Apache Commons Pool 配置参数详细解释
  • 太速科技-132-4路14bit 125Msps PCIe采集卡
  • CentOS7下的 OpenSSH 服务器和客户端
  • (二)当人工智能是一个函数,函数形式怎么选择?ChatGPT的函数又是什么?
  • 使用Apache PDFBox将pdf文件转换为图片
  • Java重要面试名词整理(二十一):SpringSecurity
  • Python爬虫基础——百度新闻页面结构剖析
  • MySQL:安装配置(完整教程)
  • 散度与旋度的探讨
  • 《ChatGPT介绍》
  • TCP/IP 教程
  • Flink源码解析之:如何根据JobGraph生成ExecutionGraph
  • uniapp H5 对接 声网,截图
  • 【技术新浪潮】DeepSeek-V3:中国AI的开源巨浪,全球AI格局的破局者
  • C# 设计模式:装饰器模式与代理模式的区别
  • 力扣hot100——二叉树
  • 高效使用AI完成编程项目任务的指南:从需求分析到功能实现