在上一篇文章中,使用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的单元格里,完美!
领取专属 10元无门槛券
私享最新 技术干货