【EasyExcel等比例缩小导出图片】

embedded/2024/11/17 0:29:56/

EasyExcel等比例缩小导出图片

  • 一、背景
  • 二、思路
  • 三、代码

一、背景

  • 使用EasyExcel导出excel文件,但是需要同时导出图片信息,且图片信息不能影响行高和单元格宽度,图片本身被导出时,不能因为压缩导致图片变形

二、思路

  • 使用EasyExcel最主要是要实现各种hadler,通过实现CellWriteHandler,获取单元格图片,进行图片压缩;
  • 由于excel的行高和单元格宽度换算方式完全不一样,所以要通过计算得出最合适的压缩比例
  • (excel宽度 / 字符宽度转换为标准字符宽度) * 估算的字符到像素的转换因子 = 宽度像素;
  • (excel高度 / 点转换为英寸) * 英寸转换为像素 = 行高像素;
  • 最终宽度像素或者行高像素 根据行高与像素的转换因子 ,计算出需要设置的单元格间距值,即可正常缩小图片

三、代码

java">public static class QuotationCustomCellWriteHandler implements CellWriteHandler {// 256分之一的字符宽度转换为标准字符宽度。public static final int STANDARD_CHARACTER_WIDTH = 256;// 7.5是一个估算的字符到像素的转换因子public static final float CHARACTER_2_PIXEL_FACTOR = 7.5f;// 将点转换为英寸,因为1点 = 1/72英寸。public static final int PIXEL_2_INCH_FACTOR = 72;// 英寸转换为像素,其中96是常用的DPI(每英寸像素数)值。public static final int DPI = 96;// 行高与像素的转换因子public static final float ROW_HEIGHT_2_PIXEL_FACTOR = 1.3333f;/*** 外界传入的行高,内部查不到*/private final int rowHeight;public QuotationCustomCellWriteHandler(int rowHeight) {this.rowHeight = rowHeight;}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex,Boolean isHead) {boolean noImageValue = Objects.isNull(cellData) || cellData.getImageDataList() == null || cellData.getImageDataList().isEmpty();if (Objects.equals(Boolean.TRUE, isHead) || noImageValue) {return;}Sheet sheet = cell.getSheet();ImageData imageData = cellData.getImageDataList().get(0);imageData.setRelativeLastRowIndex(0);imageData.setRelativeLastColumnIndex(0);// 处理图像缩放 - 等比例缩放try (ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getImage())) {BufferedImage image = ImageIO.read(bis);int targetWidth = (int) ((double) sheet.getColumnWidth(cell.getColumnIndex()) / STANDARD_CHARACTER_WIDTH * CHARACTER_2_PIXEL_FACTOR);int targetHeight = (int) (rowHeight * 1.0 / PIXEL_2_INCH_FACTOR * DPI);// 计算图像的缩放比例double scaleX = (double) targetWidth / image.getWidth();double scaleY = (double) targetHeight / image.getHeight();double scale = Math.min(scaleX, scaleY);// 计算缩放后的图像大小int scaledWidth = (int) (image.getWidth() * scale);int scaledHeight = (int) (image.getHeight() * scale);// 计算上下左右四个角的空白int topPadding = (targetHeight - scaledHeight) / 2;int bottomPadding = targetHeight - scaledHeight - topPadding;int leftPadding = (targetWidth - scaledWidth) / 2;int rightPadding = targetWidth - scaledWidth - leftPadding;// 行高(点)= 像素高度 / 1.3333imageData.setTop((int) (topPadding / ROW_HEIGHT_2_PIXEL_FACTOR));imageData.setBottom((int) (bottomPadding / ROW_HEIGHT_2_PIXEL_FACTOR));imageData.setLeft((int) (leftPadding / ROW_HEIGHT_2_PIXEL_FACTOR));imageData.setRight((int) (rightPadding / ROW_HEIGHT_2_PIXEL_FACTOR));} catch (Exception e) {log.error("QuotationCustomCellWriteHandler afterCellDataConverted err", e);}CellWriteHandler.super.afterCellDataConverted(writeSheetHolder, writeTableHolder, cellData, cell, head, relativeRowIndex, isHead);}}

http://www.ppmy.cn/embedded/138129.html

相关文章

Tomcat 8.5 源码导读

Tomcat 是一个流行的开源 Java Servlet 容器&#xff0c;负责执行 Java Servlets 和呈现 Web 应用程序。Tomcat 8.5 是一个常用版本&#xff0c;理解其核心代码对于开发和运维人员来说非常重要。下面是对 Tomcat 8.5 核心代码的一些关键部分的导读&#xff1a; 1. 启动过程 B…

gitlab容器的迁移(部署)并配置自动备份

gitlab容器的迁移&#xff08;部署&#xff09;并配置自动备份 本文背景为从Ubuntu服务器上迁移gitlab容器到windows并备份&#xff0c;若要直接拉取镜直接安装配置可直接从第二小标题参考 1、原Ubuntu的gitlab容器制作为镜像 2.1 将运行的容器制为镜像 #镜像&#xff1a;i…

Flink_DataStreamAPI_源算子Source

Flink_DataStreamAPI_源算子Source 1从集合中读取数据2从文件读取数据3从Socket读取数据4从Kafka读取数据5从数据生成器读取数据Flink支持的数据类型1&#xff09;Flink的类型系统2&#xff09;Flink支持的数据类型3&#xff09;类型提示&#xff08;Type Hints&#xff09; 1从…

C++单例模式实现

单例模式&#xff08;Singleton Pattern&#xff09;是软件设计模式中的一种&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。 一、初始版本&#xff08;手动创建释放&#xff09; 一个类只有一个实例的实现方法&#xff1a; 隐藏构…

git命令提交项目

此为linux下的命&#xff0c; windows的话&#xff0c;去掉sudo即可 *转载至链接 http://www.eqicode.com/ 1、进入项目代码根目录&#xff0c;执行&#xff1a; sudo git init 把这个目录变成git可以管理的仓库。此时在文件加下&#xff0c;会出现一个 .git的隐藏文件&#…

LeetCode 40-组合总数Ⅱ

题目链接&#xff1a;LeetCode40 欢迎留言交流&#xff0c;每天都会回消息。 class Solution {List<List<Integer>> rs new ArrayList<>();LinkedList<Integer> path new LinkedList<>();public List<List<Integer>> combinatio…

【golang-技巧】-线上死锁问题排查-by pprof

1.背景 由于目前项目使用 cgo golang 本地不能debug, 发生死锁问题&#xff0c;程序运行和期待不一致&#xff0c;通过日志排查可以大概率找到 阻塞范围&#xff0c;但是不能找到具体问题在哪里&#xff0c;同时服务器 通过k8s daemonset 部署没有更好的方式暴露端口 获取ppr…

开发中SQL积累

1.SQL中判断varchar类型是否为空&#xff1f; 检查 NULL 值&#xff1a; WHERE column_name IS NULL 检查空字符串&#xff1a; WHERE column_name 结合 NULL 和空字符串的检查&#xff1a; WHERE column_name IS NULL OR column_name 2.TRIM函数 作用&#xff1a;…