数据操作:复杂字段类型的导入导出
若期望导出的字段来自该模型所关联对象中的某一字段,那么在创建模板时,需采用 “对象.字段” 的形式 。并且,在执行导出操作时,要手动设置该字段。举例而言,对于 PamirsEmployee 模型中的 company 关联对象,可通过 company.name 的方式创建对应的值用于导出。
一、模型定义
@Field.many2one
@Field.Relation(relationFields = {"companyCode"}, referenceFields = {"code"})
@Field(displayName = "所属公司")
private PamirsCompany company;//定义员工导入导出模版
@Component
public class EmployeeTemplate implements ExcelTemplateInit {
    public static final String TEMPLATE_NAME = "employeeTemplate";
    @Override
    public List<ExcelWorkbookDefinition> generator() {
        //可以返回多个模版,导出的时候页面上由用户选择导出模版
        return Collections.singletonList(
            ExcelHelper.fixedHeader(PetShop.MODEL_MODEL, TEMPLATE_NAME)
            .createBlock(TEMPLATE_NAME, PetShop.MODEL_MODEL)
            .setType(ExcelTemplateTypeEnum.EXPORT)
            //使用company.name获取PamirsCompany里面的name字段
            .addColumn("company.name", "所属公司")
            .build());
    }
}
//手动设置该字段,如2所示二、代码示例
(一)非存储字段的导出
若期望导出的字段为非存储字段,鉴于默认情况下仅导出存储于数据库中的字段,因而针对非存储字段,需在导出时进行手动设置 。
@Slf4j
@Component
@Ext(ExcelExportTask.class)
public class EmpTemplateExportExtPoint extends DefaultExcelExportFetchDataExtPoint {
        @Override
        @ExtPoint.Implement(expression = "context.name==\"" + EmployeeTemplate.TEMPLATE_NAME + "\"")
        public List<Object> fetchExportData(ExcelExportTask exportTask, ExcelDefinitionContext context) {
            return super.fetchExportData(exportTask, context);
        }
        //重写rawQueryList方法,使用listFieldQuery将非存储字段单独设置
        @Override
        protected List<?> rawQueryList(IWrapper<?> wrapper) {
            List<PamirsEmployee> pamirsEmployeeProxies = (List<PamirsEmployee>) Models.data().queryListByWrapper(wrapper);
            if (CollectionUtils.isNotEmpty(pamirsEmployeeProxies)) {
                new PamirsEmployee().listFieldQuery(pamirsEmployeeProxies, PamirsEmployee::getDepartmentList);
            }
          return pamirsEmployeeProxies;
        }
}(二)多值字段导入
若所需导入的字段存在多个值的情况,可创建一个代理模型。在此代理模型中,设置一个字段用于接收该多值字段。具体操作方式为,在 Excel 中,于一个单元格内填写多值字段,每个字段之间使用自定义符号(例如:“;”)进行分割。在创建模板时,使用该代理类对应的模板。在执行导入与导出操作时,再依据 “;” 对字段进行截取处理。
@Model.model(PamirsEmployeeProxy.MODEL_MODEL)
@Model(displayName = "员工导出代理")
@Model.Advanced(type = ModelTypeEnum.PROXY)
public class PamirsEmployeeProxy extends PamirsEmployee {
        private static final long serialVersionUID = -6582160484690807999L;
        public static final String MODEL_MODEL = "business.PamirsEmployeeProxy";
        @Field.String
        @Field(displayName = "部门编码列表")
        private String departmentCodeList;
}创建模版时创建代理模型的字段
.addColumn("departmentCodeList", "部门编码列表")导入操作:创建一个新类,将其作为导入功能的扩展点,该类需继承 AbstractExcelImportDataExtPointImpl 类 。
@Component
@Ext(ExcelImportTask.class)
@Slf4j
public class EmpTemplateImportExtPoint extends AbstractExcelImportDataExtPointImpl<PamirsEmployeeProxy> {
    //必须加这个方法,它使用EmployeeTemplate.TEMPLATE_NAME来指定导入模版
    @Override
    @ExtPoint.Implement(expression = "importContext.definitionContext.name==\"" + EmployeeTemplate.TEMPLATE_NAME + "\"")
    public Boolean importData(ExcelImportContext importContext, PamirsEmployeeProxy data) {
        //TODO 根据逻辑校验数据
        String departmentCodeList = data.getDepartmentCodeList();
        if (StringUtils.isNotEmpty(departmentCodeList)) {
            String[] departmentCodes = departmentCodeList.split(";");
            ....
        }
        return true;
    }
}导出操作:创建一个新类,将其作为导出功能的扩展点,该类需继承 DefaultExcelExportFetchDataExtPoint 类。
@Slf4j
@Component
@Ext(ExcelExportTask.class)
@SuppressWarnings({"unchecked"})
public class EmpTemplateExportExtPoint extends DefaultExcelExportFetchDataExtPoint {
    //必须加这个方法,它使用EmployeeTemplate.TEMPLATE_NAME来指定导出模版
    @Override
    @ExtPoint.Implement(expression = "context.name==\"" + EmployeeTemplate.TEMPLATE_NAME + "\"")
    public List<Object> fetchExportData(ExcelExportTask exportTask, ExcelDefinitionContext context) {
        //TODO 根据逻辑校验数据
        return super.fetchExportData(exportTask, context);
    }
    @Override
    protected List<?> rawQueryList(IWrapper<?> wrapper) {
        //TODO 根据逻辑校验行数据
        List<PamirsEmployeeProxy> pamirsEmployeeProxies = (List<PamirsEmployeeProxy>) Models.data().queryListByWrapper(wrapper);
        if (CollectionUtils.isNotEmpty(pamirsEmployeeProxies)) {
            new PamirsEmployeeProxy().listFieldQuery(pamirsEmployeeProxies, PamirsEmployeeProxy::getDepartmentList);
            for (PamirsEmployeeProxy pamirsEmployeeProxy : pamirsEmployeeProxies) {
                List<PamirsDepartment> departmentList = pamirsEmployeeProxy.getDepartmentList();
                if (CollectionUtils.isNotEmpty(departmentList)) {
                    pamirsEmployeeProxy.setDepartmentCodeList(departmentList.stream()
                                                              .map(PamirsDepartment::getCode)
                                                              .collect(Collectors.joining(";")));
                }
            }
        }
        return pamirsEmployeeProxies;
    }
}