手摸手系列之EasyPoi导出Excel横向遍历实战

前言

技术栈:
SpringBoot 2.3.1.RELEASE
Vue 2.x
EasyPoi 4.4.0

最近做前后端分离项目,遇到一个导出对账单的需求,还都是些不规则的Excel,其中一个境外飞机进口的需求如下:

手摸手系列之EasyPoi导出Excel横向遍历实战_第1张图片

每一列是一票台账,每行展示的是左侧表头的所列的具体的费用金额。而且每个sheet最多展示7个台账,超过的就多加一个sheet。因此我们知道,把每一列作为数据集合的一个元素,然后直接用EasyPOI的横向遍历+sheet clone功能就可轻易实现。官方文档[点我直达]

一、定义导出数据实体对象ExportExcelEntityForStatement,因为跟别的导出功能共用,所以会有一些无用的字段

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;

/**
 * 

* 对账单表自定义导出用 *

* * @author ZHANGCHAO * @since 2022-07-18 */
@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class ExportExcelEntityForStatement implements Serializable { private static final long serialVersionUID = 1L; /** * 台账号 */ private String accountNo; /** * 提单号 */ private String awbNo; /** * 件数 舱单信息 */ private Integer packs; /** * 计费重量 */ private BigDecimal chargedWeight; /** * 件数/重量Pcs/Weight */ private String packsChargedWeight; /** * 费用描述 */ private String moneyName; /** * 总价 */ private BigDecimal amount; /** * 税率 */ private BigDecimal tax; /** * 开票税率 */ private BigDecimal fpTax; /** * 发票税 */ private BigDecimal invoiceTax; /** * 合计 */ private BigDecimal totalAmount; /** * 备注说明 */ private String remarkNote; /** * 出库手续费 */ private BigDecimal outgoingBondedWarehouseAmount; /** * 航空运费 */ private BigDecimal airfreightAmount; /** * 目的港派送 */ private BigDecimal dDuChargeAmount; /** * 操作费 */ private BigDecimal handlingChargeAmount; /** * 空空中转费 */ private BigDecimal transferDeclarationFeeAmount; /** * 单证服务费 */ private BigDecimal ducomentationAmount; /** * 机场杂费 */ private BigDecimal terminalChargeAmount; /** * 外库费用 */ private BigDecimal outsideTheLibraryFeeAmount; /** * 监管仓库操作服务费 */ private BigDecimal bondedHandingChargeAmount; /** * 舱单信息处理费 */ private BigDecimal manifestFeeAmount; /** * 单证费 */ private BigDecimal documentFeeAmount; /** * 危品操作费 */ private BigDecimal handlingChargeForDgAmount; /** * 危品包装费 */ private BigDecimal uNPackingChargeAmount; /** * 作业单平台使用费 */ private BigDecimal handlingPlatformChargeAmount; /** * 制单费 */ private BigDecimal documentsMakingAmount; /** * 报关报检代理服务费 */ private BigDecimal customsClearanceFeeAmount; /** * 录单劳务费 */ private BigDecimal dataPutInChargeAmount; /** * 地面处理费 */ private BigDecimal terminalChargeInTnaAmount; /** * 国外港杂费 */ private BigDecimal oversesaHarbourChargeAmount; /** * 国外提货费 */ private BigDecimal overseasPickupChargeAmount; /** * 仓储费 */ private BigDecimal storageChargeAmount; /** * 装卸费 */ private BigDecimal loadingAndUnloadingFeeAmount; /** * 国内普货运输 */ private BigDecimal inlandFreightAmount; /** * 特殊货物处理费 */ private BigDecimal handlingChargeForSpecialGoodsAmount; /** * 叉车服务费 */ private BigDecimal forkliftHandlingChargesAmount; /** * 检验检测鉴定服务费 */ private BigDecimal dGmAmount; /** * 危品申报费 */ private BigDecimal declaredForDgAmount; /** * 入库手续费 */ private BigDecimal incomingBondedWarehouseAmount; /** * 铲车服务费 */ private BigDecimal forkliftServiceChargeAmount; /** * 货物查验费 */ private BigDecimal cargoCheckingFeeAmount; /** * 分舱单费 */ private BigDecimal cargoManifestChangeAmount; /** * AOG费 */ private BigDecimal overtimeWorkChargeAmount; /** * 代垫费 */ private BigDecimal reimbursedExpensesAmount; /** * 消毒、熏蒸代理费 */ private BigDecimal disinfectionChargeAmount; private String feiyongType; private String curr; }

二、根据对账单的ID集合查询数据的xml

<select id="exportImportOfOverseasAircraft"
            resultType="com.yorma.finance.entity.dto.ExportExcelEntityForStatement">
        SELECT
            a.ACCOUNT_NO,
            CASE

                WHEN ( c.M_BILL_NO IS NOT NULL AND c.M_BILL_NO != '' ) THEN
                    c.M_BILL_NO ELSE c.HBL
                END awbNo,
            c.PACKS,
            c.CHARGED_WEIGHT,
            CASE

                WHEN ( b.MEMO IS NOT NULL AND b.MEMO != '' ) THEN
                    b.MEMO ELSE b.`DESC`
                END moneyName,
            b.AMOUNT,
            a.MEMO remarkNote,
            b.TAX,
            b.FP_TAX,
            b.CURR,
            b.TYPE feiyongType
        FROM
            `ACCOUNT` a
                LEFT JOIN ACCOUNT_EXPENSE b ON a.ACCOUNT_NO = b.ACCOUNT_NO
                LEFT JOIN APPLY c ON c.ACCOUNT_NO = a.ACCOUNT_NO
                LEFT JOIN ACCOUNT_PUT_REL d ON d.EXP_ID = b.ID
                LEFT JOIN ACCOUNT_STATEMENT f ON f.ID = d.CLA_ID
        WHERE
            f.ID IN
        <foreach collection="idList" item="id" index="index" open="(" close=")" separator=",">
            #{id}
        foreach>
        AND b.CURR = 'CNY'
    select>

三、主要的导出实现方法

 /**
     * 导出对账单
     * 11-境外飞机进口
     * 12-日本飞机进口
     * 13-太古进口新
     * 14-太古出口新
     *
     * @param ids        对账单id拼接串
     * @param exportType 对账单类型
     * @return com.yorma.entity.YmMsg
     * @apiNote 
     *   导出对账单
     * 
* @author ZHANGCHAO 2022/8/4 13:28 * @version 1.0 */
@Override public YmMsg<String> exportImportOfOverseasAircraft(String ids, String exportType) { if (isBlank(ids)) { return YmMsg.error("参数[对账单ID]不能为空!"); } if (isBlank(exportType)) { return YmMsg.error("参数[导出类型]不能为空!"); } String templateUrl = ""; if ("11".equals(exportType)) { templateUrl = templatesPath + "境外飞机进口.xls"; } else if ("12".equals(exportType)) { templateUrl = templatesPath + "日本飞机进口.xls"; } else if ("13".equals(exportType)) { templateUrl = templatesPath + "太古进口新.xls"; } else if ("14".equals(exportType)) { templateUrl = templatesPath + "太古出口新.xls"; } TemplateExportParams params = new TemplateExportParams(templateUrl); params.setColForEach(true); params.setSheetName(new String[]{"1"}); List<ExportExcelEntityForStatement> exportExcelEntityForStatementList = baseMapper.exportImportOfOverseasAircraft(Arrays.asList(ids.split(","))); if (isEmpty(exportExcelEntityForStatementList)) { return YmMsg.error("未获取到数据,无法导出!"); } // 类型 1应收 2应支 String type = exportExcelEntityForStatementList.get(0).getFeiyongType(); List<Map<String, Object>> numOneList = new ArrayList<>(); // 处理数据!! List<Map<String, Object>> colList = getColList(exportExcelEntityForStatementList, exportType); // 每7个一组,再次分组 List<List<Map<String, Object>>> subColList = CollUtil.split(colList, 7); int i = 0; // 此循环是分sheet的关键,subColList有几个subList就分几个sheet for (List<Map<String, Object>> subList : subColList) { i++; Map<String, Object> value = new HashMap<>(); value.put("subList", subList); value.put("title", "太古飞机中英文进口货物对帐单Incoming goods Debit Note"); value.put(SHEET_NAME, i); // 每个sheet的sheet名称 numOneList.add(value); } // 反转 Collections.reverse(numOneList); // 因为EasyPOI生成Excel后会按集合的顺序反着生成,所以咱给集合反转一下顺序。 Map<Integer, List<Map<String, Object>>> realMap = new HashMap<>(); realMap.put(0, numOneList); Workbook workbook = ExcelExportUtil.exportExcelClone(realMap, params); ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { workbook.write(bos); } catch (IOException e) { e.printStackTrace(); } finally { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } byte[] data = bos.toByteArray(); String prefix = ""; if ("11".equals(exportType)) { if ("1".equals(type)) { prefix = "境外飞机进口-应收对账单-"; } else { prefix = "境外飞机进口-应支对账单-"; } } else if ("12".equals(exportType)) { if ("1".equals(type)) { prefix = "日本飞机进口-应收对账单-"; } else { prefix = "日本飞机进口-应支对账单-"; } } else if ("13".equals(exportType)) { if ("1".equals(type)) { prefix = "太古进口新-应收对账单-"; } else { prefix = "太古进口新-应支对账单-"; } } else if ("14".equals(exportType)) { if ("1".equals(type)) { prefix = "太古出口新-应收对账单-"; } else { prefix = "太古出口新-应支对账单-"; } } String fileName = prefix + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + RandomUtil.randomString(6) + ".xls"; String xmlPath = download + File.separator + fileName; File file = new File(xmlPath); FileOutputStream fos; try { fos = new FileOutputStream(file); fos.write(data, 0, data.length); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } String path = xmlPath.substring(xmlPath.lastIndexOf(File.separator) + 1); String filePath = viewPdfPath + path; log.info("[exportImportOfOverseasAircraft]生成文件成功:==> " + filePath); return YmMsg.ok(filePath); }

境外飞机进口、日本飞机进口、太古进口新、太古出口新:模板差不多,只是费用有所不同,其他取值和逻辑都一样。此处只是以境外飞机进口为例。

最后是生成文件的下载地址返回给前端,前端通过nginx下载。

代码注释很完整,可以参考注释来理解。

四、主要的数据处理方法

/**
 * 获取Excel数据
 *
 * @param exportExcelEntityForStatementList
 * @return java.util.List>
 * @author ZHANGCHAO
 * @date 2022/8/8 9:27
 */
private List<Map<String, Object>> getColList(List<ExportExcelEntityForStatement> exportExcelEntityForStatementList, String exportType) {
    List<Map<String, Object>> colList = new ArrayList<>();
    Map<String, List<ExportExcelEntityForStatement>> excelEntityMap = exportExcelEntityForStatementList.stream()
            .collect(Collectors.groupingBy(ExportExcelEntityForStatement::getAccountNo));
    excelEntityMap = sortMapByKey(excelEntityMap);
    if (isNotEmpty(excelEntityMap)) {
        excelEntityMap.forEach((k, v) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("accountNo", k); // 台账号
            map.put("awbNo", isNotEmpty(v) ? v.get(0).getAwbNo() : ""); // 提单号
            map.put("packsChargedWeight", "0/0.00 KG"); // 件数重量
            if (isNotEmpty(v)) {
                List<String> packsChargedWeightList = new ArrayList<>(16);
                packsChargedWeightList.add(isNotEmpty(v.get(0).getPacks()) ? String.valueOf(v.get(0).getPacks()) : "0");
                packsChargedWeightList.add(isNotEmpty(v.get(0).getChargedWeight()) ? String.valueOf(v.get(0).getChargedWeight().setScale(2, RoundingMode.HALF_UP)) : "0.00");
                String packsChargedWeight = CollUtil.join(packsChargedWeightList, "/") + " KG"; // 件数重量
                map.put("packsChargedWeight", packsChargedWeight); // 件数重量
                // 处理导出对账单的各个费用数据
                dealEveryAmounts(map, v, exportType);
                // 备注说明
                map.put("remarkNote", v.get(0).getRemarkNote());
            }
            colList.add(map);
        });
    }
    return colList;
}

 /**
* 使用 Map按key进行排序
*
* @param map
* @return
*/
private static Map<String, List<ExportExcelEntityForStatement>> sortMapByKey(Map<String, List<ExportExcelEntityForStatement>> map) {
    if (map == null || map.isEmpty()) {
        return null;
    }
    Map<String, List<ExportExcelEntityForStatement>> sortMap = new TreeMap<>(
            new MapKeyComparator());
    sortMap.putAll(map);
    return sortMap;
}
  
 /**
 * 设置费用金额
 *
 * @param map
 * @param v
 * @param exportType
 * @return void
 * @author ZHANGCHAO
 * @date 2022/8/9 8:13
 */
public static void dealEveryAmounts(Map<String, Object> map, List<ExportExcelEntityForStatement> v, String exportType) {
    BigDecimal bijiaoyong = new BigDecimal("0.00000");
    // 类型 1应收 2应支
    String type = v.get(0).getFeiyongType();
    // 境外飞机进口
    if ("11".equals(exportType)) {
        // 航空运费
        BigDecimal airfreightAmount = v.stream().filter(i -> "航空运费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("airfreightAmount", bijiaoyong.compareTo(airfreightAmount) != 0 ? airfreightAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 操作费
        BigDecimal handlingChargeAmount = v.stream().filter(i -> "操作费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("handlingChargeAmount", bijiaoyong.compareTo(handlingChargeAmount) != 0 ? handlingChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 单证服务费
        BigDecimal ducomentationAmount = v.stream().filter(i -> "单证服务费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("ducomentationAmount", bijiaoyong.compareTo(ducomentationAmount) != 0 ? ducomentationAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 机场杂费
        BigDecimal terminalChargeAmount = v.stream().filter(i -> "机场杂费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("terminalChargeAmount", bijiaoyong.compareTo(terminalChargeAmount) != 0 ? terminalChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 监管仓库操作服务费
        BigDecimal bondedHandingChargeAmount = v.stream().filter(i -> "监管仓库操作服务费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("bondedHandingChargeAmount", bijiaoyong.compareTo(bondedHandingChargeAmount) != 0 ? bondedHandingChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 舱单信息处理费
        BigDecimal manifestFeeAmount = v.stream().filter(i -> "舱单信息处理费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("manifestFeeAmount", bijiaoyong.compareTo(manifestFeeAmount) != 0 ? manifestFeeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 单证费
        BigDecimal documentFeeAmount = v.stream().filter(i -> "单证费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("documentFeeAmount", bijiaoyong.compareTo(documentFeeAmount) != 0 ? documentFeeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 危品操作费
        BigDecimal handlingChargeForDgAmount = v.stream().filter(i -> "危品操作费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("handlingChargeForDgAmount", bijiaoyong.compareTo(handlingChargeForDgAmount) != 0 ? handlingChargeForDgAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 作业单平台使用费
        BigDecimal handlingPlatformChargeAmount = v.stream().filter(i -> "作业单平台使用费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("handlingPlatformChargeAmount", bijiaoyong.compareTo(handlingPlatformChargeAmount) != 0 ? handlingPlatformChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 报关报检代理服务费
        BigDecimal customsClearanceFeeAmount = v.stream().filter(i -> "报关报检代理服务费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("customsClearanceFeeAmount", bijiaoyong.compareTo(customsClearanceFeeAmount) != 0 ? customsClearanceFeeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 国外港杂费
        BigDecimal oversesaHarbourChargeAmount = v.stream().filter(i -> "国外港杂费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("oversesaHarbourChargeAmount", bijiaoyong.compareTo(oversesaHarbourChargeAmount) != 0 ? oversesaHarbourChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 国外提货费
        BigDecimal overseasPickupChargeAmount = v.stream().filter(i -> "国外提货费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("overseasPickupChargeAmount", bijiaoyong.compareTo(overseasPickupChargeAmount) != 0 ? overseasPickupChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 仓储费
        BigDecimal storageChargeAmount = v.stream().filter(i -> "仓储费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("storageChargeAmount", bijiaoyong.compareTo(storageChargeAmount) != 0 ? storageChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 装卸费
        BigDecimal loadingAndUnloadingFeeAmount = v.stream().filter(i -> "装卸费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("loadingAndUnloadingFeeAmount", bijiaoyong.compareTo(loadingAndUnloadingFeeAmount) != 0 ? loadingAndUnloadingFeeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 国内普货运输
        BigDecimal inlandFreightAmount = v.stream().filter(i -> "国内普货运输".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("inlandFreightAmount", bijiaoyong.compareTo(inlandFreightAmount) != 0 ? inlandFreightAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 特殊货物处理费
        BigDecimal handlingChargeForSpecialGoodsAmount = v.stream().filter(i -> "特殊货物处理费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("handlingChargeForSpecialGoodsAmount", bijiaoyong.compareTo(handlingChargeForSpecialGoodsAmount) != 0 ? handlingChargeForSpecialGoodsAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 入库手续费
        BigDecimal incomingBondedWarehouseAmount = v.stream().filter(i -> "入库手续费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("incomingBondedWarehouseAmount", bijiaoyong.compareTo(incomingBondedWarehouseAmount) != 0 ? incomingBondedWarehouseAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 铲车服务费
        BigDecimal forkliftServiceChargeAmount = v.stream().filter(i -> "铲车服务费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("forkliftServiceChargeAmount", bijiaoyong.compareTo(forkliftServiceChargeAmount) != 0 ? forkliftServiceChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 货物查验费
        BigDecimal cargoCheckingFeeAmount = v.stream().filter(i -> "货物查验费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("cargoCheckingFeeAmount", bijiaoyong.compareTo(cargoCheckingFeeAmount) != 0 ? cargoCheckingFeeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 分舱单费
        BigDecimal cargoManifestChangeAmount = v.stream().filter(i -> "分舱单费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("cargoManifestChangeAmount", bijiaoyong.compareTo(cargoManifestChangeAmount) != 0 ? cargoManifestChangeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // AOG费
        BigDecimal overtimeWorkChargeAmount = v.stream().filter(i -> "AOG费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("overtimeWorkChargeAmount", bijiaoyong.compareTo(overtimeWorkChargeAmount) != 0 ? overtimeWorkChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 代垫费
        BigDecimal reimbursedExpensesAmount = v.stream().filter(i -> "代垫费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("reimbursedExpensesAmount", bijiaoyong.compareTo(reimbursedExpensesAmount) != 0 ? reimbursedExpensesAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 消毒、熏蒸代理费
        BigDecimal disinfectionChargeAmount = v.stream().filter(i -> "消毒、熏蒸代理费".equals(i.getMoneyName()) && isNotEmpty(i.getAmount()))
                .map(ExportExcelEntityForStatement::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        map.put("disinfectionChargeAmount", bijiaoyong.compareTo(disinfectionChargeAmount) != 0 ? disinfectionChargeAmount.setScale(2, RoundingMode.HALF_UP) : "");
        // 发票税
        map.put("invoiceTax", "");
        if (isNotEmpty(v)) {
            BigDecimal invoiceTax = BigDecimal.ZERO;
            for (ExportExcelEntityForStatement entityForStatement : v) {
                if (isNotBlank(entityForStatement.getMoneyName()) && moneyName_11_List.contains(entityForStatement.getMoneyName())) {
                    if ("1".equals(type)) {
                        if (isNotEmpty(entityForStatement.getTax()) && entityForStatement.getTax().compareTo(new BigDecimal("6.00")) == 0) {
                            BigDecimal everyInvoiceTax = (isNotEmpty(entityForStatement.getAmount()) ? entityForStatement.getAmount() : BigDecimal.ZERO)
                                    .multiply(entityForStatement.getTax()).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);
                            invoiceTax = invoiceTax.add(everyInvoiceTax);
                        }
                    } else if ("2".equals(type)) {
                        if (isNotEmpty(entityForStatement.getFpTax()) && entityForStatement.getFpTax().compareTo(new BigDecimal("6.00")) == 0) {
                            BigDecimal everyInvoiceTax = (isNotEmpty(entityForStatement.getAmount()) ? entityForStatement.getAmount() : BigDecimal.ZERO)
                                    .multiply(entityForStatement.getFpTax()).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);
                            invoiceTax = invoiceTax.add(everyInvoiceTax);
                        }
                    }
                }
            }
            map.put("invoiceTax", new BigDecimal("0.00").compareTo(invoiceTax) != 0 ? invoiceTax : "");
        }
        BigDecimal totalAmount = airfreightAmount.add(handlingChargeAmount).add(ducomentationAmount).add(terminalChargeAmount)
                .add(bondedHandingChargeAmount).add(manifestFeeAmount).add(documentFeeAmount).add(handlingChargeForDgAmount)
                .add(handlingPlatformChargeAmount).add(customsClearanceFeeAmount).add(oversesaHarbourChargeAmount)
                .add(overseasPickupChargeAmount).add(storageChargeAmount).add(loadingAndUnloadingFeeAmount).add(inlandFreightAmount)
                .add(handlingChargeForSpecialGoodsAmount).add(incomingBondedWarehouseAmount).add(forkliftServiceChargeAmount).add(cargoCheckingFeeAmount)
                .add(cargoManifestChangeAmount).add(overtimeWorkChargeAmount).add(reimbursedExpensesAmount).add(disinfectionChargeAmount);
        // 合计
        map.put("totalAmount", totalAmount);
    }
}


五、设置Excel模版

手摸手系列之EasyPoi导出Excel横向遍历实战_第2张图片

标题是合并单元格,长度是集合subList的长度+2,#fe表示横向遍历集合subList。

六、最终导出Excel

手摸手系列之EasyPoi导出Excel横向遍历实战_第3张图片

你可能感兴趣的:(springboot,vue,Mybatis,java,开发语言)