EasyExcel - table写入复杂表头及内容

需求:在一个工作簿中,需要填充固定字段信息,并写入多个不同的标题列的表格及内容。
常规Excel写入一般是一个工作簿一个表头。

一、复杂表单分析

1.表单示例

复杂表单示例1

2.复杂表单拆解

复杂表单示例拆解
示例的模板,可以拆解为6个组成部分:
(1)1-7行:表格固定的部分,需要在指定的单元格动态填充信息
(2)8-10行:表格动态写入的部分,由【工单器材】的字段列标题和内容组成。
(3)11-13行:表格动态写入的部分,由【工单服务】的字段列标题和内容组成。
(4)14行:表格动态写入的部分,由【工单结论】的字段列标题组成
(5)15-16行:表格动态写入的部分,由【费用计算】的字段列标题组成
(6)17-19行:表格固定的部分,但是因为无法往表格中间插入table,所以此处只能将固定的格式数据以table方法写入,由【表格固定结尾】的字段内容组成。

3.准备模板

因为表格的前7行是固定格式的,为了简化操作,我们直接将格式定好作为模板。而余下的行是根据数据量动态写入的。
那么,我们在代码中需要对该模板进行填充写入的操作。
在这里插入图片描述

二、EasyExcel文档

有了以上思路,开始翻阅easyExcel文档,查找可以使用的方法。最终确定使用以下两个方法去实现。

1.最简单的填充Excel

用于填充固定模板中的指定字段。
在这里插入图片描述

2.使用table去写入

用于写入动态的标题和内容。
在这里插入图片描述

三、代码示例

1.实体类

工单模板的信息来源于工单信息、工单申请信息、工单设备申请明细、工单服务申请明细表。

1)工单信息表

/**
 * 工单信息表
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
public class WorkOrderInfo implements Serializable {
   

	// 工单ID
    private Long workOrderId;

	// 工单号码
    private String workOrderCode;

    // 发起人名称
    private String creatorName;

    // 处理人名称
    private String handerName;

    // 工单标题
    private String workOrderTitle;
    
	// 工单内容
    private String workOrderContent;

   // 工单结论
    private String workOrderResult;
}

2)工单申请信息表

/**
 * 工单申请信息表
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
public class WorkOrderApplyInfo implements Serializable {
   

	// 工单申请id
    private Long workOrderApplyId;

	// 工单id
    private Long workOrderId;
    
 	// 工单上门次数
    private String visitNum;
    
	// 工单单次支付(元)
    private String singlePay;
    
 	// 工单总计费用(元)
    private String totalPay;

    // 设备申请明细
    private List<WorkOrderDevice> deviceList;

    // 服务申请明细
    private List<WorkOrderService> serviceList;
}

3)工单设备申请明细表

/**
 * 工单设备申请明细表
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
public class WorkOrderDevice implements Serializable {
   

	// 工单设备申请明细id
    private Long workOrderDeviceId;

	// 工单id
    private Long workOrderId;
    
	// 工单申请id
    private Long workOrderApplyId;
    
 	// 设备名称
    private String deviceName;
    
	// 设备明数
    private String deviceContent;
    
 	// 申请数量
    private String applyNum;
}

4)工单服务申请表

/**
 * 工单服务申请明细表
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
public class WorkOrderService implements Serializable {
   

	// 工单设备申请明细id
    private Long workOrderServiceId;

	// 工单id
    private Long workOrderId;
    
	// 工单申请id
    private Long workOrderApplyId;
    
 	// 服务名称
    private String serviceName;
    
	// 服务描述
    private String serviceContent;
    
 	// 申请工时(时)
    private String hourNum;
}

2.工具类

1)内容导出工具类

因为该模板中不同的table,标题不同,占用合并的列数对应字段也不同。所以此处将设备、服务、工单结论、费用合计、固定结尾的【标题】、【字段映射列及列数】分别单独设置。最后通过【字段映射列及列数】和实际数据,构造【内容】列。

tips:
excel写入实际上是一行一行的写入数据
一行的数据结构是List<String>
多行的数据结构是List<List<String>>
/**
 * 工单确认单内容导出工具类
 */
@Component
@Slf4j
public class WorkOrderDataUtils {
   

	// >>>>>>>>>>>>>>> 标题构造 >>>>>>>>>>>>>>>>>>>>>>>>>>>
    /**
     * 设备列表标题
     * @return
     */
    public static List<List<String>> deviceHead() {
   
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("工单器材");
        // 占用3列
        list.add(head0);
        list.add(head0);
        list.add(head0);

        List<String> head1 = new ArrayList<String>();
        head1.add("器材描述");
        // 占用2列
        list.add(head1);
        list.add(head1);

        List<String> head2 = new ArrayList<String>();
        head2.add("数量");
        // 占用两列
        list.add(head2);
        list.add(head2);
        return list;
    }

	/**
     * 服务列表标题
     * @return
     */
    public static List<List<String>> serviceHead() {
   
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("工单服务");
        // 占用3列
        list.add(head0);
        list.add(head0);
        list.add(head0);

        List<String> head1 = new ArrayList<String>();
        head1.add("服务描述");
        // 占用2列
        list.add(head1);
        list.add(head1);

        List<String> head2 = new ArrayList<String>();
        head2.add("工时");
        // 占用两列
        list.add(head2);
        list.add(head2);
        return list;
    }

	/**
     * 工单结论标题:
     * 将结论传入作为标题
     * @return
     */
    public static List<List<String>> workOrderResultHead(String workOrderResult) {
   
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("工单结论");
        // 占用3列
        list.add(head0);
        list.add(head0);
        list.add(head0);

        List<String> head1 = new ArrayList<String>();
        head1.add(workOrderResult);
        // 占用4列
        list.add(head1);
        list.add(head1);
        list.add(head1);
        list.add(head1);

        return list;
    }
	/**
     * 费用合计标题
     * 将上门次数,每次支付(元),总费用传入作为标题
     * @return
     */
    public static List<List<String>> totalHead(String visitNum, String singlePay, String totalPay) {
   
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("上门次数");
        head0.add(visitNum);

        // 占用3列
        list.add(head0);
        list.add(head0);
        list.add(head0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值