easyExcel应用

打印A4数据 引用easyExcel模板实现

Y.实现功能

1).批量数据填充
2).批量数据超过范围实现分页
3).不同类型数据引用不同模板
4).每页模板需插入特定数据条形码图片
5).分页实现引用多sheet方法实现
6).excel转pdf用于打印

Y. pom引用包

<!-- easyExcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

<!--条形码-->
<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.barcode.free</artifactId>
    <version>2.6.2-RELEASE</version>
</dependency>
<!--pdf-->
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-cells</artifactId>
    <version>8.5.2-RELEASE</version>
</dependency>

<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.pdf</artifactId>
    <version>4.8.1-RELEASE</version>
</dependency>
E. 模板配置

在这里插入图片描述
excel样例
在这里插入图片描述

S.实现代码
S-Y. excel合并单元格

继承AbstractMergeStrategy

public class ExcelMergeStrategy extends AbstractMergeStrategy {
    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if(relativeRowIndex==null ||relativeRowIndex==0){
            return;
        }
        int rowIndex = cell.getRowIndex();
        int colIndex = cell.getColumnIndex();
        sheet=cell.getSheet();
        Row preRow = sheet.getRow(rowIndex - 1);
        Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
        List<CellRangeAddress> list = sheet.getMergedRegions();
        CellStyle cs = cell.getCellStyle();
        cell.setCellStyle(cs);
        for (int i = 0; i < list.size(); i++) {
            CellRangeAddress cellRangeAddress = list.get(i);
            if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) {
                int lastColIndex = cellRangeAddress.getLastColumn();
                int firstColIndex = cellRangeAddress.getFirstColumn();
                CellRangeAddress cra = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), firstColIndex, lastColIndex);
                sheet.addMergedRegion(cra);
                return;
            }
        }

    }

}
S-E. 工具类

1). 生成条形码 barCodeUtil

/**
 * 生成条形码(类型=Code_128)
 * params barCodeString 生成条形码字符串
 * params widht 图宽
 * params height 图高
 * params showText 是否展示条形码下方字符串
 * @return 条形码的byte[]
 */
@SneakyThrows
public static ByteArrayOutputStream barcodeImageToOutPutStream(String barCodeString, Integer widht, Integer height,Boolean showText) {
    BarcodeSettings settings = new BarcodeSettings();
    settings.setType(BarCodeType.Code_128);
    settings.setData(barCodeString);
    settings.setShowText(showText);
    settings.setShowTextOnBottom(true);
//        settings.setImageHeight(1.32f);
//        settings.setImageWidth(6.4f);
    settings.setAutoResize(true);
    //设置边框不可见
    settings.hasBorder(false);
    BarCodeGenerator barCodeGenerator = new BarCodeGenerator(settings);
    BufferedImage bufferedImage = barCodeGenerator.generateImage();
    if (height != null && widht != null) {
        bufferedImage = resize(bufferedImage, height, widht);
    }
//        String uuidString = UUID.randomUUID().toString();
//        File file = new File(uuidString + ".png");
//        ImageIO.write(bufferedImage,"png",file);
//        return file;
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ImageIO.write(bufferedImage, "png", outputStream);
//        byte[] bytes = outputStream.toByteArray();
//        outputStream.close();

//        String a = BarcodeScanner.scanOne(new ByteArrayInputStream(outputStream.toByteArray()));
    return outputStream;
    }

2). List分组 ListUtil
切分数组转成 List<List>

 /**
 * 将集合按len数量分成若干个list
 * @param list
 * @param len 每个集合的数量
 * @return
 */
public static <T> List<List<T>> splitList(List<T> list, int len) {
    if (list == null || list.size() == 0 || len < 1) {
        return null;
    }
    List<List<T>> result = new ArrayList<List<T>>();

    int size = list.size();
    int count = (size + len - 1) / len;

    for (int i = 0; i < count; i++) {
        List<T> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
        result.add(subList);
    }
    return result;
}

/**
 * @param list
 * @return
 */
public static <T> List<List<T>> averageAssign(List<T> list,int n){
    List<List<T>> result=new ArrayList<List<T>>();
    int remaider=list.size()%n;  //(先计算出余数)
    int number=list.size()/n;  //然后是商
    int offset=0;//偏移量
    for(int i=0;i<n;i++){
        List<T> value=null;
        if(remaider>0){
            value=list.subList(i*number+offset, (i+1)*number+offset+1);
            remaider--;
            offset++;
        }else{
            value=list.subList(i*number+offset, (i+1)*number+offset);
        }
        result.add(value);
    }
    return result;
}

3). 生成Pdf PdfUtil
excel转pdf

public class PdfUtil {

    public static boolean getLicense1() {
        boolean result = false;
        try {

            InputStream is = PdfUtil.class.getClassLoader()
                    .getResourceAsStream("license.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下
            com.aspose.cells.License aposeLic = new com.aspose.cells.License();
            aposeLic.setLicense(is);
            result = true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * excel转pdf 默认为a4纸大小
     * @param excelFileName 
     * @param pdfFileName
     * @return
     */
    public static Boolean excelToPdf(String excelFileName, String pdfFileName) {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense1()) {
            return false;
        }

        try {
            //文件操作
            File file = new File(pdfFileName); // 新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Workbook wb = new Workbook(excelFileName);// 原始excel路径
            FileOutputStream fileOS = new FileOutputStream(file);
            wb.save(fileOS, com.aspose.cells.SaveFormat.PDF);
            fileOS.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * excel转pdf 
     * @param excelFileName 
     * @param pdfFileName
     * @param paperSizeType  纸张大小
     * @return
     */
    public static Boolean excelToPdfV2(String excelFileName, String pdfFileName,int paperSizeType) {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense1()) {
            return false;
        }

        try {
            //文件操作
            File file = new File(pdfFileName); // 新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);

            Workbook wb = new Workbook(excelFileName);// 原始excel路径
            int pageSize = wb.getWorksheets().getCount();
            for (int i = 0; i < pageSize; i++) {
                Worksheet worksheet = wb.getWorksheets().get(i);
                worksheet.getPageSetup().setPaperSize(paperSizeType);
            }
            FileOutputStream fileOS = new FileOutputStream(file);
            wb.save(fileOS, com.aspose.cells.SaveFormat.PDF);
            fileOS.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
public String printPickingOrders(List<ServiceOrderPo> params) {
    // 第一页数量
    int firstNum = ServiceOrderConstants.ExcelValue.firstNum;
    // 平均数量
    int avgNum = ServiceOrderConstants.ExcelValue.avgNum;
    
    //excel模板
    String templateFileName = "C:\\Users\\Administrator\\Desktop\\excel\\模板.xlsx";
    File file = new File(templateFileName);
    
    // 定义模板sheet数量
    AtomicInteger num = new AtomicInteger(2);
    
    @Cleanup XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
    //设置sheetNo1的模板名称 用于记录
    workbook.setSheetName(0, "模板1");
    //设置sheetNo2的名称 用于记录
    workbook.setSheetName(1, "模板2");
    
    @Cleanup XSSFWorkbook finalWorkbook = workbook;
    
    // 页数
    AtomicInteger size = new AtomicInteger(0);
    // sheet名后缀
    AtomicInteger sheetNum = new AtomicInteger(1);
    serviceOrderPos.forEach(serviceOrderPo -> {
        // 明细列表数据
        List<EntrustItemPo> entrustItemPos = entrustItemMap.get(serviceOrderPo.getServiceNo());
        if (CollectionUtils.isEmpty(entrustItemPos))return;
        // 当前单页数
        int pageSize = (entrustItemPos.size() - firstNum) > 0 ? (entrustItemPos.size() - firstNum) / avgNum + 2 : 1;
    
        // 3).不同类型数据引用不同模板  根据需求克隆sheet模板
        for (int i = 0; i < pageSize; i++) {
            if (!serviceOrderPo.getCrossBorderFlag()) {
                finalWorkbook.cloneSheet(1, "sheet" + (sheetNum.get()));
            } else {
                finalWorkbook.cloneSheet(0, "sheet" + (sheetNum.get()));
            }
            sheetNum.getAndIncrement();
        }
    
        for (int i = 0; i < pageSize; i++) {
            XSSFDrawing patriarch = finalWorkbook.getSheetAt(size.get() + 2).createDrawingPatriarch();
            // 生成条形码
            ByteArrayOutputStream barCodeImageFile = ExcelUtil.barcodeImageToOutPutStream(serviceOrderPo.getServiceNo(), 280, 80, false);
            //放置条形码位置
            XSSFClientAnchor anchor = new XSSFClientAnchor();
            if (!serviceOrderPo.getCrossBorderFlag()) {
                anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 5, 2, (short) 7, 3);
            } else {
                anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 5, 2, (short) 6, 3);
            }
            // 插入条形码
            patriarch.createPicture(anchor, finalWorkbook.addPicture(barCodeImageFile.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
            size.getAndIncrement();
        }
    });
    
    // 删除模板sheet并 写入流
    finalWorkbook.removeSheetAt(1);
    finalWorkbook.removeSheetAt(0);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    finalWorkbook.write(bos);
    
    byte[] bArray = bos.toByteArray();
    @Cleanup InputStream byteArrayInputStream = new ByteArrayInputStream(bArray);
    // 填充数据
    ExcelWriter  excelWriter =EasyExcel.write(filePath).withTemplate(byteArrayInputStream).registerWriteHandler(new ExcelMergeStrategy()).build();
    FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
    
    serviceOrderPos.forEach(serviceOrderPo -> {
        // 明细列表数据
        List<EntrustItemPo> entrustItemPos = entrustItemMap.get(serviceOrderPo.getServiceNo());
        if (CollectionUtils.isEmpty(entrustItemPos))return;
        // 切分数据 新增多sheet分页
        List<List<EntrustItemPo>> groupList = ListUtil.splitList(entrustItemPos, avgNum);
        for (int i = 0; i < groupList.size(); i++) {
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet" + (num.get() - 1)).build();
            writeSheet.setSheetNo(num.get() - 2);
    
            //填充到表头数据
            Map map = new HashMap<String, Object>();
            map.put("orderIdOut", serviceOrderPo.getRelationCode());
            map.put("billLadingNo", serviceOrderPo.getBillLadingNo());
            map.put("inStoreNo", String.join("\n", serviceNoMap.get(serviceOrderPo.getServiceNo())));
            map.put("serviceNo", serviceOrderPo.getServiceNo());
            map.put("printDate", printDate);
            map.put("currentSize", i + 1);
            map.put("pageSize", groupList.size());
    
            // 统计数据
            AtomicReference<Integer> totalPackageNumber = new AtomicReference<>(0);
            AtomicReference<BigDecimal> totalWeight = new AtomicReference<>(new BigDecimal(BigInteger.ZERO));
            AtomicReference<BigDecimal> totalVolume = new AtomicReference<>(new BigDecimal(BigInteger.ZERO));
            entrustItemPos.forEach(po -> {
                totalPackageNumber.updateAndGet(v -> v + po.getEntrustNum());
                totalVolume.set(totalVolume.get().add(Objects.isNull(po.getEntrustVolume()) ? BigDecimal.ZERO : po.getEntrustVolume()));
                totalWeight.set(totalWeight.get().add(Objects.isNull(po.getEntrustWeight()) ? BigDecimal.ZERO : po.getEntrustWeight()));
            });
    
            if (i == groupList.size() - 1) {
                map.put("totalData", "汇总数据");
                map.put("totalPackageNumber", totalPackageNumber.toString());
                map.put("totalWeight", String.valueOf(totalWeight));
                map.put("totalVolume", String.valueOf(totalVolume));
                map.put("tray", "托盘数量");
                map.put("trayNumber", entrustItemPos.size());
            }
    
            // 列表数据
            List<Map<String, Object>> paramsList = new ArrayList<>();
            groupList.get(i).forEach(detail -> {
                Map<String, Object> paramsMap = new MapUtils()
                        .put("stagingAreaCode", Objects.nonNull(stagingAreaMap.get(detail.getTrayNo())) ? stagingAreaMap.get(detail.getTrayNo()).getStagingAreaCode() : null)
                        .put("trayNo", detail.getTrayNo())
                        .put("packageNumber", detail.getEntrustNum())
                        .put("weight", detail.getEntrustWeight())
                        .put("volume", detail.getEntrustVolume())
                        .put("goldjetTrayFlag", detail.getGoldjetTrayFlag())
                        .put("createTime", stagingAreaMap.get(detail.getTrayNo()).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")));
                paramsList.add(paramsMap);
            });
    
            excelWriter.fill(map, writeSheet);
            excelWriter.fill(paramsList, fillConfig, writeSheet);
            num.getAndIncrement();
        }
    
    });
    excelWriter.finish();
    // excel转pdf
    Stirng pdfPath="C:\\Users\\Administrator\\Desktop\\excel\\"+UUID.randomUUID().toString().replace("-","")+".pdf";
    PdfUtil.excelToPdf(fileName, pdfPath);
    System.out.println(pdfPath);
    File file = new File(filePath);
    if (file.exists() && file.isFile()) {
        file.delete();
    }
    return null;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值