EasyExcel导出-自适应图像尺寸

背景

  《EasyExcel导出-自适应图像尺寸》最近在使用EasyExcel进行图像数据导出的时候,需要在单元格内自适应缩放图像,防止图像被拉伸。。

效果

  图像备份: 访问

easyexcel-export-image.jpg

实现

package cn.net.pap.common.excel.handle;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Objects;

public class ImageModifyHandler implements CellWriteHandler {

    // 256分之一的字符宽度转换为标准字符宽度。
    public static Integer standardCharacterWidth = 256;

    // 7.5是一个估算的字符到像素的转换因子
    public static Float character2PixelFactor = 7.5f;

    // 将点转换为英寸,因为1点 = 1/72英寸。
    public static Integer pixel2InchFactor = 72;

    // 英寸转换为像素,其中96是常用的DPI(每英寸像素数)值。
    public static Integer dpi = 96;

    // 行高与像素的转换因子
    public static Float rowHeight2PixelFactor = 1.3333f;


    /**
     * 后单元格数据转换
     *
     * @param writeSheetHolder 写单夹
     * @param writeTableHolder 写表夹
     * @param cellData         单元格数据
     * @param cell             细胞
     * @param head             头
     * @param relativeRowIndex 相对行索引
     * @param isHead           是头
     */
    @Override
    public 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().size() == 0;
        if (Objects.equals(Boolean.TRUE, isHead) || noImageValue) {
            return;
        }
        Sheet sheet = cell.getSheet();
        int mergeColumNum = getMergeColumNum(cell, sheet);
        int mergeRowNum = getMergeRowNum(cell, sheet);
        ImageData imageData = cellData.getImageDataList().get(0);
        imageData.setRelativeLastRowIndex(mergeRowNum - 1);
        imageData.setRelativeLastColumnIndex(mergeColumNum - 1);

        // 处理图像缩放 - 等比例缩放
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getImage());
            java.awt.image.BufferedImage image = ImageIO.read(bis);
            int targetWidth = (int)(sheet.getColumnWidth(cell.getColumnIndex()) / standardCharacterWidth * character2PixelFactor);
            int targetHeight = (int)(cell.getRow().getHeightInPoints() / pixel2InchFactor * 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.3333
            imageData.setTop((int)(topPadding/rowHeight2PixelFactor));
            imageData.setBottom((int)(bottomPadding/rowHeight2PixelFactor));
            imageData.setLeft((int)(leftPadding/rowHeight2PixelFactor));
            imageData.setRight((int)(rightPadding/rowHeight2PixelFactor));

            bis.close();
        } catch (Exception e) {
        }

        CellWriteHandler.super.afterCellDataConverted(writeSheetHolder, writeTableHolder, cellData, cell, head, relativeRowIndex, isHead);
    }


    /**
     * 得到合并行num
     *
     * @param cell  细胞
     * @param sheet 表
     * @return int
     */
    public static int getMergeRowNum(Cell cell, Sheet sheet) {
        int mergeSize = 1;
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
        for (CellRangeAddress cellRangeAddress : mergedRegions) {
            if (cellRangeAddress.isInRange(cell)) {
                //获取合并的行数
                mergeSize = cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow() + 1;
                break;
            }
        }
        return mergeSize;
    }

    /**
     * 得到合并列num
     *
     * @param cell  细胞
     * @param sheet 表
     * @return int
     */
    public static int getMergeColumNum(Cell cell, Sheet sheet) {
        int mergeSize = 1;
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
        for (CellRangeAddress cellRangeAddress : mergedRegions) {
            if (cellRangeAddress.isInRange(cell)) {
                //获取合并的列数
                mergeSize = cellRangeAddress.getLastColumn() - cellRangeAddress.getFirstColumn() + 1;
                break;
            }
        }
        return mergeSize;
    }

}


参考

  1. http://pap-docs.pap.net.cn/
  2. https://gitee.com/alexgaoyh/pap4j-boot3/blob/master/pap4j-common/pap4j-common-excel/src/main/java/cn/net/pap/common/excel/handle/ImageModifyHandler.java
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
easyexcel导出图片自适应的方法如下: 1. 首先,确保你已经添加了easyexcel的依赖。在pom.xml文件中添加以下代码: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.1</version> </dependency> ``` 2. 创建一个导出实体类,该实体类中需要包含需要导出图片字段。例如: ```java @Data @AllArgsConstructor @NoArgsConstructor public class ExcelFeedbackVO extends Feedback { // 其他字段...... @ExcelProperty(value = "图片", index = 4) private String imageUrl; } ``` 3. 修改对外暴露的接口,使其支持导出图片。在`EasyExcel.write()`方法中添加`.registerWriteHandler(new ImageWriteHandler())`,并确保你的`ExcelFeedbackVO`实体类中包含了图片字段。例如: ```java @PostMapping("/downloadBack") public void downloadBack(HttpServletResponse response, String siteId, Integer content) throws TException, IOException { List<Feedback> list = feedbackService.searchBack(siteId, content); setResponse(response, "列表"); EasyExcel.write(response.getOutputStream(), ExcelFeedbackVO.class) .sheet("列表") .registerWriteHandler(new ImageWriteHandler()) // 导出图片 .registerWriteHandler(new CustomCellWriteWidthConfig()) // 自适应列宽 .registerWriteHandler(new CustomCellWriteHeighConfig()) // 自适应行高 .registerWriteHandler(EasyExcelUtils.getStyleStrategy()) // 引用样式 .doWrite(list); } ``` 至此,你已经可以使用easyexcel导出包含图片的Excel,并实现了图片自适应
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值