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

7 篇文章 1 订阅
4 篇文章 0 订阅
前言

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

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

请添加图片描述

每一列是一票台账,每行展示的是左侧表头的所列的具体的费用金额。而且每个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;

/**
 * <p>
 * 对账单表自定义导出用
 * </p>
 *
 * @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<java.lang.String>
     * @apiNote <pre>
     *   导出对账单
     * </pre>
     * @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<java.util.Map < java.lang.String, java.lang.Object>>
 * @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模版

请添加图片描述

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

六、最终导出Excel

请添加图片描述

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是使用EasyPoi导出ExcelJava代码示例[^1]: 1. 首先,确保你已经引入了EasyPoi的依赖库。 2. 创建一个实体类,用于存储导出的数据。例如,创建一个名为"ExcelExport"的类,并使用@Excel注解来指定Excel中的列名和属性名。 ```java import cn.afterturn.easypoi.excel.annotation.Excel; import lombok.Data; @Data public class ExcelExport { @Excel(name = "姓名") private String name; @Excel(name = "年龄") private int age; // 其他属性... } ``` 3. 编写导出方法,使用EasyPoi提供的工具类进行导出操作。例如,创建一个名为"ExcelUtils"的工具类,并在其中编写导出方法。 ```java import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import org.apache.poi.ss.usermodel.Workbook; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class ExcelUtils { public static void exportExcel() throws IOException { // 创建导出的数据列表 List<ExcelExport> dataList = new ArrayList<>(); dataList.add(new ExcelExport("张三", 20)); dataList.add(new ExcelExport("李四", 25)); dataList.add(new ExcelExport("王五", 30)); // 创建导出参数 ExportParams exportParams = new ExportParams(); exportParams.setType(ExcelType.XSSF); // 导出Excel文件 Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ExcelExport.class, dataList); FileOutputStream fos = new FileOutputStream("导出文件路径"); workbook.write(fos); fos.close(); } } ``` 4. 调用导出方法进行导出操作。 ```java public class Main { public static void main(String[] args) { try { ExcelUtils.exportExcel(); System.out.println("导出成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 请注意,上述代码中的"导出文件路径"需要替换为你希望导出Excel文件的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值