首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring Boot整合Apache的poi框架,导出大图片到excel中严重变形,一个方法解决它

在上一篇文章中,使用Spring Boot整合Apache的poi框架,导出功能轻松实现,测试数据也十分完美。

放到线上去,像素小一点的图片没有问题,像素大一点的图片就膨胀开来,跑到 excel 单元格的外面,占据了半个页面,严重变形,没法看。

在图片多的地方,图片更是重叠在一起,不分彼此。真是反了天了。

大一点的图片能不能等比例缩小?试试看吧,图片最大限制在300像素以内。

在插入图片的方法里进行调整。

private void insertImage(Workbook workbook, Sheet sheet, int rowIndex, int colIndex, String imageNetPath){try{if(StringUtils.isEmpty(imageNetPath)){return;}// 图片处理,把网络处理成本地图片String imagePath = null;if(imageNetPath.substring(0, imageNetPath.indexOf(":")).equalsIgnoreCase("https")){imagePath = imageNetPath.split("\\?")[0].replace("https://ip地址/images/", uploadPath);}else{imagePath = imageNetPath.split("\\?")[0].replace("http://ip地址/images/", uploadPath);}log.info("图片地址:{}", imagePath);// 获取文件资源File imageFile = new File(imagePath);// 图片不存在就不需要处理了if(!imageFile.exists()){return;}// 载入图片BufferedImage image = ImageIO.read(imageFile);// 图片大小限制,等比例缩放int maxDimension = 300;BufferedImage resizedImage = scaleImage(image, maxDimension);// 将图片写入字节数组输出流,以便插入到 ExcelByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(resizedImage, "png", baos);byte[] imageBytes = baos.toByteArray();

// 读取图片数据int pictureIndex = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG);// 创建帮助类和绘图对象CreationHelper helper = workbook.getCreationHelper();// 创建锚点设置图片位置@SuppressWarnings("rawtypes")Drawing drawing = sheet.createDrawingPatriarch();ClientAnchor anchor = helper.createClientAnchor();anchor.setCol1(colIndex); // 图片起始列anchor.setRow1(rowIndex); // 图片起始行 // 插入图片Picture picture = drawing.createPicture(anchor, pictureIndex);

// 获取图片高度并设置行高,一定要先设置高度,然后再调整图片大小,否则图片会变形double imageHeightInPoints = picture.getImageDimension().getHeight() * 0.75; // 转换为 Excel 点, 0.75:每像素点数Row row = sheet.getRow(rowIndex);if (row == null) {row = sheet.createRow(rowIndex);}row.setHeightInPoints((float) imageHeightInPoints);

// 调整图片大小picture.resize(); }catch(Exception e){e.printStackTrace();}}

首先,这个方法做了微调。

增加 File 对象对源文件进行判断,文件不存在就不要继续处理了。

其次,在这个方法里又新增了一个私有方法。

图片缩放的处理方法:

// 图片缩放方法private BufferedImage scaleImage(BufferedImage originalImage, int maxDimension) { // 获取图片的宽高int originalWidth = originalImage.getWidth();int originalHeight = originalImage.getHeight();// 计算缩放比例double scale = Math.min((double) maxDimension / originalWidth, (double) maxDimension / originalHeight);if (scale >= 1.0) {// 如果图片尺寸已经小于最大尺寸,返回原图return originalImage;}int newWidth = (int) (originalWidth * scale);int newHeight = (int) (originalHeight * scale);// 创建缩放后的图片Image scaledInstance = originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = scaledImage.createGraphics();g2d.drawImage(scaledInstance, 0, 0, null);g2d.dispose();return scaledImage;}

图片缩放的逻辑非常简单。

第一步,首先获取图片真实的宽和高。

第二步,计算缩放比例。

用限制尺寸除以原宽和原高,获取缩放比例。

第三步,根据缩放比例返回对应的BufferedImage 对象。

如果缩放比例大于或等于1,说明这个图片没有超过大小限制,直接返回原图的originalImage对象。

如果缩放比例小于1,说明这个图片需要缩放,根据比例重新绘制新的scaledImage 对象并返回。

调整后测试,再大的图片也安安稳稳地落在了excel的单元格里,完美!

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OBfwNiMn5uTnAENh7Y1XyW2g0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券