POI XSSF 多张图片导出到一个单元格实现

此代码示例演示了如何使用Apache POI库在Excel工作表中创建多个单元格,并在每个单元格中插入同一张图片,然后根据预设的长宽比例调整图片大小。通过ClientAnchor设置图片位置,resize方法调整图片尺寸,最终保存为xlsx文件。
摘要由CSDN通过智能技术生成
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.usermodel.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author loomis
 * @Date 2021/11/24 11:10
 * @Version 1.0
 */
public class test
{
    public static void main(String[] args) {
        FileOutputStream fileOut = null;
        BufferedImage bufferImg = null;//logo
        ByteArrayOutputStream byteArrayOut = null; //读进图片

        XSSFWorkbook wb = new XSSFWorkbook();

        try {
            // 先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
            byteArrayOut = new ByteArrayOutputStream();
            //将图片读到BufferedImage
            bufferImg = ImageIO.read(new File("C:\\Users\\Administrator\\Pictures\\20211009144818.png"));
            // 将图片写入流中
            ImageIO.write(bufferImg, "png", byteArrayOut);


            XSSFSheet sheet = wb.createSheet("123");
            Row row = sheet.createRow(1);
            Cell cell = row.createCell(1);
            // 设置列宽
            sheet.setColumnWidth(1, 256 * 38);
            // 设置行高
            row.setHeightInPoints((short) 20);
            // 指定我想要的长宽
            int standardWidth = 50;
            int standardHeight = 25;

            // 计算单元格的长宽
            double cellWidth = sheet.getColumnWidthInPixels(cell.getColumnIndex());
            double cellHeight = cell.getRow().getHeightInPoints() / 72 * 96;

            // 计算需要的长宽比例的系数
            double a = standardWidth / cellWidth;
            double b = standardHeight / cellHeight;
            /**anchor主要用于设置图片的属性
             * 该构造函数有8个参数
             * 前四个参数是控制图片在单元格的位置,分别是图片距离单元格left,top,right,bottom的像素距离
             * 后四个参数,前两个表示图片左上角所在的cellNum和 rowNum,后两个参数对应的表示图片右下角所在的cellNum和 rowNum,
             * excel中的cellNum和rowNum的index都是从0开始的
             *
             */
            XSSFDrawing patriarch = sheet.createDrawingPatriarch();
            CreationHelper helper = wb.getCreationHelper();
            ClientAnchor anchor = helper.createClientAnchor();
            anchor.setRow1(1);
            anchor.setCol1(1);
            anchor.setDx1(0);
            anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE);//设置图片随单元移动调整大小
            XSSFPicture picture = patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
            picture.resize(a,b);
            ClientAnchor anchor2 = helper.createClientAnchor();
            anchor2.setRow1(1);
            anchor2.setCol1(1);
            anchor2.setDx1((standardWidth-10)* Units.EMU_PER_POINT);
            anchor2.setDx2((standardWidth-10)* Units.EMU_PER_POINT);
            XSSFPicture picture2 = patriarch.createPicture(anchor2, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
            // 计算需要的长宽比例的系数
            picture2.resize(a,b);
            ClientAnchor anchor3 = helper.createClientAnchor();
            anchor3.setRow1(1);
            anchor3.setCol1(1);
            anchor3.setDx1((standardWidth-10)*2* Units.EMU_PER_POINT);
            anchor3.setDx2((standardWidth-10)*2* Units.EMU_PER_POINT);
            XSSFPicture picture3 = patriarch.createPicture(anchor3, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
            picture3.resize(a,b);
            ClientAnchor anchor4 = helper.createClientAnchor();
            anchor4.setRow1(1);
            anchor4.setCol1(1);
            anchor4.setDx1((standardWidth-10)*3* Units.EMU_PER_POINT);
            anchor4.setDx2((standardWidth-10)*3* Units.EMU_PER_POINT);
            XSSFPicture picture4 = patriarch.createPicture(anchor4, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
            picture4.resize(a,b);
            ClientAnchor anchor5 = helper.createClientAnchor();
            anchor5.setRow1(1);
            anchor5.setCol1(1);
            anchor5.setDx1((standardWidth-10)*4* Units.EMU_PER_POINT);
            anchor5.setDx2((standardWidth-10)*4* Units.EMU_PER_POINT);
            XSSFPicture picture5 = patriarch.createPicture(anchor5, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
            picture5.resize(a,b);
            //生成的excel文件地址
            fileOut = new FileOutputStream("D:\\123.xlsx");
            // 写入excel文件
            wb.write(fileOut);
        } catch (Exception io) {
            io.printStackTrace();
            System.out.println("io erorr : " + io.getMessage());
        } finally {
            if (fileOut != null) {
                try {
                    fileOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
优化这段代码: @Override public void exportExcel120(CertfInfoOrderQueryVo vo, HttpServletResponse response) { try { // 根据id查询数据 Page<DasymesCertfInfoPojo> page = new Page<>(1, 10); IPage<DasymesCertfInfoPojo> iPage = infoMapper.openQuery(page, vo); List<DasymesCertfInfoPojo> dataList = iPage.getRecords(); if (dataList == null || dataList.size() == 0) return; // 获取下载模板 InputStream template = DasymesQltyMpCertfInfoModServiceImpl.class.getClassLoader().getResourceAsStream("交付120厂产品合格证.xlsx"); if (template == null) return; DasymesCertfInfoPojo info = dataList.get(0); // 获取静态数据 Map<String, String> staticSource = getStaticSource(info); // 获取动态数据 List<DynamicSource> dynamicSourceList = getDynamicSourceList(info.getAttachedList()); Map<ByteArrayOutputStream, XSSFClientAnchor> imgMap = new HashMap<>(); ByteArrayOutputStream userByteArrayOut = new ByteArrayOutputStream(); File file = new File("D:\hegezhengtupian\"+ UserCache.getThreadLocalUser().getUserRealName() +".png"); if (file.canRead()) { bufferImg = ImageIO.read(file); ImageIO.write(bufferImg, "png", userByteArrayOut); XSSFClientAnchor userAnchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 13, 2, 14); userAnchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); imgMap.put(userByteArrayOut, userAnchor); } Workbook workbook = ExcelTemplateUtil.buildByTemplate(template, staticSource, dynamicSourceList, imgMap); ExcelTemplateUtil.save(workbook, "交付120厂产品合格证", response); // ExcelTemplateUtil.save(workbook, "D:\工作\文档\template.xlsx"); } catch (Exception e) { throw new RuntimeException("导出失败,请联系管理员"); } } // 编辑动态数据 private List<DynamicSource> getDynamicSourceList(List<DasymesQltyMpCertfInfoItemMod> itemModList) { List<Map<String, String>> mapList = new ArrayList<>(); if (itemModList == null || itemModList.size() == 0) { Map<String, String> map = new HashMap<>(); map.put("no", null); map.put("name", null); map.put("portion", null); mapList.add(map); return DynamicSource.createList("detail", mapList); } for (int i = 1; i <= itemModList.size(); i++) { DasymesQltyMpCertfInfoItemMod item = itemModList.get(i - 1); Map<String, String> map = new HashMap<>(); map.put("no", i + ""); map.put("name", item.getItemName()); map.put("portion", item.getPortion()); mapList.add(map); } return DynamicSource.createList("detail", mapList); }
06-03
1. 将方法拆分成更小的方法,提高可读性和可维护性。 2. 使用 try-with-resources 语句来自动关闭资源。 3. 对于文件路径,使用 File.separator 替代硬编码的路径分隔符。 4. 避免使用 magic number ,使用常量或枚举类型来代替。 5. 在使用集合时,使用 isEmpty() 方法代替 size() == 0。 6. 使用 stream() 方法来代替 for 循环。 7. 使用 lambda 表达式来代替匿名内部类。 8. 在捕获异常时,应该尽可能地捕获特定的异常。 优化后的代码如下: ```java @Override public void exportExcel120(CertfInfoOrderQueryVo vo, HttpServletResponse response) { try (InputStream template = DasymesQltyMpCertfInfoModServiceImpl.class.getClassLoader().getResourceAsStream("交付120厂产品合格证.xlsx")) { Page<DasymesCertfInfoPojo> page = new Page<>(1, PAGE_SIZE); IPage<DasymesCertfInfoPojo> iPage = infoMapper.openQuery(page, vo); List<DasymesCertfInfoPojo> dataList = iPage.getRecords(); if (dataList.isEmpty()) { return; } DasymesCertfInfoPojo info = dataList.get(0); Map<String, String> staticSource = getStaticSource(info); List<DynamicSource> dynamicSourceList = getDynamicSourceList(info.getAttachedList()); Map<ByteArrayOutputStream, XSSFClientAnchor> imgMap = getImageMap(); Workbook workbook = ExcelTemplateUtil.buildByTemplate(template, staticSource, dynamicSourceList, imgMap); ExcelTemplateUtil.save(workbook, "交付120厂产品合格证", response); } catch (IOException e) { throw new RuntimeException("导出失败,请联系管理员"); } } private Map<String, String> getStaticSource(DasymesCertfInfoPojo info) { Map<String, String> staticSource = new HashMap<>(); staticSource.put("certfNo", info.getCertfNo()); staticSource.put("prodName", info.getProdName()); staticSource.put("spec", info.getSpec()); staticSource.put("prodNo", info.getProdNo()); staticSource.put("prodDate", info.getProdDate()); staticSource.put("expDate", info.getExpDate()); staticSource.put("prodUnit", info.getProdUnit()); staticSource.put("prodAddr", info.getProdAddr()); staticSource.put("qualityGrade", info.getQualityGrade()); staticSource.put("packing", info.getPacking()); staticSource.put("remark", info.getRemark()); return staticSource; } private List<DynamicSource> getDynamicSourceList(List<DasymesQltyMpCertfInfoItemMod> itemModList) { List<Map<String, String>> mapList = new ArrayList<>(); if (itemModList.isEmpty()) { Map<String, String> map = new HashMap<>(); map.put("no", null); map.put("name", null); map.put("portion", null); mapList.add(map); return DynamicSource.createList("detail", mapList); } return itemModList.stream() .map(item -> { Map<String, String> map = new HashMap<>(); map.put("no", String.valueOf(itemModList.indexOf(item) + 1)); map.put("name", item.getItemName()); map.put("portion", item.getPortion()); return map; }) .collect(Collectors.collectingAndThen(Collectors.toList(), DynamicSource::createList)); } private Map<ByteArrayOutputStream, XSSFClientAnchor> getImageMap() throws IOException { Map<ByteArrayOutputStream, XSSFClientAnchor> imgMap = new HashMap<>(); ByteArrayOutputStream userByteArrayOut = new ByteArrayOutputStream(); File file = new File("D:" + File.separator + "hegezhengtupian" + File.separator + UserCache.getThreadLocalUser().getUserRealName() + ".png"); if (file.canRead()) { BufferedImage bufferImg = ImageIO.read(file); ImageIO.write(bufferImg, "png", userByteArrayOut); XSSFClientAnchor userAnchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 13, 2, 14); userAnchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); imgMap.put(userByteArrayOut, userAnchor); } return imgMap; } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值