Java Web导出等比例图片到Excel

做个Excel导入导出的Java开发户都知道,可以利用Apache的POI来实现,为Excel创建每一行,每一单元及对应的内容。当然,图片的话需要用到POI中的HSSFClientAnchor这个类型来实现, HSSFClientAnchor的构造函数中有八个参数,分类为:int dx1,int dy1,int dx2,int dy2,short col1,int row1,short col2, int row2,其中dx1、dy1定义了该图片在开始cell的起始位置,dx2、dy2定义了在终cell的结束位置,col1、row1定义了开始cell、col2、row2定义了结束cell。

那么,我们就可以用这个方法来讲图片定位到每一个单元格中。我的做法是:

铺满整个单元格,这里的j和i是代码中要到处多张图做了循环定义的变量HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) j, i + 1, (short) j, i + 1);

很顺利,成功导出!

问题来了,打开成功到处的Excel一看,商品对应的图片都很规矩的按照我的设置铺满了整个单元格。但是,商品图片却都变形了,也就是图片的 宽高被强行设置了成对应单元格的宽高。

这样肯定是不行的,于是第一反应就是将图片等比例导出,但是怎么让图片等比例的导出在Excel中呢,苦恼了许久,终于想到了一个可行的方案。就是利用POI设置每一行对应要放图片的那个单元格的宽度固定,也就是所有导出的图片的宽度固定,然后根据这个固定宽度与原图宽高对比,算出该固定宽度的等比例高度,然后动态设置该单元格的高度,然后再利用HSSFClientAnchor来铺满整个单元格,这样看起来就不会变形,而且等比例缩放到指定单元格中。

关键2步实现:

第一步 设置单元格固定宽度: 循环创建每一行的时候,如何设置要放图片的那个单元的宽度呢?大家都知道,在Excel中,同一列的单元格的宽度都是一样的,故可以在创建工作簿的时候,就设定好要放图片的那个单元格的宽度,我是这样做的:

生成一个表格 HSSFSheet sheet = workbook.createSheet(title);

设置B列的宽度为 30*256; sheet.setColumnWidth(1, 30 * 256);

这里我们看到,SetColumnWidth的第二个参数要乘以256,是因为这个参数的单位是1/256个字符宽度,也就是说这里我设置的是30个字符的宽度,至于一个字符宽度是多少,可以用FontDesignMetrics来获得,一般一个12号字体的宽度大约是13像素。

第二步,设置单元等比率高度:在循环每一行中,当创建对应放图片的单元的时候,设置对应的高度。我的做法是,先获取要导出的图片,在获取图片的原始宽度和高度(主要,这里获取的是像素宽高),然后根据前面设置的固定宽度算出等比例的高度:

java 复制代码
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageIO.read(new File(savePath + System.getProperty("file.separator") + map.get("productImg")));
ImageIO.write(bufferImg, "jpg", byteArrayOut);
int width = bufferImg.getWidth();//原始宽度
int height = bufferImg.getHeight();//原始高度
// 一个12号字体的宽度为13,前面已设置了列的宽度为30*256,故这里的等比例高度计算如下
height = (int) Math.round((height * (30 * 13) * 1.0 / width));
// excel单元格高度是以点单位,1点=2像素; POI中Height的单位是1/20个点,故设置单元的等比例高度如下
row.setHeight((short) (height / 2 * 20));
// 画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
// anchor主要用于设置图片的属性
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) j, i + 1, (short) j, i + 1);
anchor.setAnchorType(3);
// 插入图片
patriarch.createPicture(anchor,workbook.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));

至此,等比率图片及相关信息以完美导出到Excel中。

相关推荐
江畔柳前堤7 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
陈随易9 小时前
moon,apt和yum之外linux系统命令安装新选择
前端·后端·程序员
码事漫谈10 小时前
当单库日增 4.5TB,异构实时同步还能稳得住吗?
后端
IT_陈寒12 小时前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
shengjk112 小时前
AI Engineering 五代演进史:Prompt、RAG、Agent 到 Graph 的架构革命
后端
子兮曰12 小时前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端
妙码生花12 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(四十八):菜单规则管理实现
前端·后端·ai编程
XuCoder12 小时前
Redis 持久化:RDB 与 AOF
后端
Conan在掘金13 小时前
鸿蒙 7.0 智能体框架 2.0:意图即服务根因——从 InsightIntentExecutor 到 HMAF 2.0 Skill 演进
后端
掘金者阿豪13 小时前
折腾电科金仓 Docker 部署的一晚上:角色登录失败、远程连接失败,这几个坑终于踩完了
后端