使用EasyExcel导出数据

使用EasyExcel导出

下载模板

导入excel功能,都需要对应的模板导入,也有动态的表头数据导入,可以看excel行数据不规则解析匹配。这里一般都是固定excel文件,存放在项目路径下面,下载模板的时候都是找对应的文件。


@GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        String fileName = "导入模板.xlsx";
        ClassPathResource classPathResource = new ClassPathResource("template/file.xlsx");
        try (InputStream inputStream = classPathResource.getInputStream();
             OutputStream out = response.getOutputStream();) {
            setResponseAttribute(fileName, response);
            Map<String, String> map = new HashMap<>(4);
            int year = DateUtil.thisYear();
            map.put("lastYear", String.valueOf(year - 1));
            map.put("currentYear", String.valueOf(year));
            ExcelWriterBuilder writerBuilder = EasyExcel.write(out).withTemplate(inputStream);
            //这边第二个sheet页面里面有个参数需要动态生成,指定了往第二个sheet页里面填充值
            writerBuilder.sheet(1).doFill(map);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }
数据下载
表头数据修改

一般导出数据固定的话都可以使用对象导入,建立对应的对象,使用EasyExcel中相应的注解,对Excel中单元格样式,字体样式,背景颜色等等都可以实现。

/**
 * 
 * @author 洛必达法则不会
 * @since 2021-07-22
 */
@Data
@HeadStyle(horizontalAlignment = HorizontalAlignment.CENTER)
@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER)
@HeadFontStyle(fontHeightInPoints = 10, fontName = "微软雅黑")
@ContentFontStyle(fontHeightInPoints = 10)
@HeadRowHeight(18)
@ColumnWidth(14)
public class TalentSituationHeadData {
    /**
     * 年份
     */
    @ColumnWidth(8)
    @ExcelProperty(value = "年份", index = 0)
    private String year;

    /**
     * 事业部
     */
    @ExcelProperty(value = "事业分部", index = 1)
    private String deptName;
    
    /**
     * 待招岗位
     */
    @ExcelProperty(value = "待招岗位", index = 2)
    private String recruitedPost;

    /**
     * 姓名
     */
    @HeadStyle(fillForegroundColor = 44)
    @ExcelProperty(value = "姓名", index = 3)
    private String name;
}

本次功能导入需要导出一个Excel包含多个sheet页,其中一个sheet页面的表头需要根据时间动态生成,直接使用@ExcelProperty注解,value值都是固定的。

// 首先尝试的通过 WriteSheet中head属性获取表头的字段,再修改里面对应的值,实际运行中属性值是null,此方法不可以
WriteSheet potentialCustomerSheet = EasyExcel.writerSheet(index,sheetNameEnum.getName()).head(PotentialCustomerHeadData.class).build();
List<List<String>> headList = potentialCustomerSheet.getHead();
//另一种就是重新构造List<List<String>> headList,通过EasyExcel.write(fileName).head(headList).sheet("模板");写入表头,这种方式在对象的字体颜色注解就没有,需要重新构造对应的格式,也比较繁琐
List<List<String>> headList = buildHeadDataList();
EasyExcel.write(fileName).head(headList).sheet("模板");
//之前的逻辑写好,不想用上面的方法,后面就采用反射的方式,拿到对应属性上面的注解,修改里面的值再通过EasyExcel.writerSheet写入
String year = StrUtil.isNotBlank(param.getStartDate())
                ? param.getStartDate().substring(0, 4)
                : Integer.toString(DateUtil.thisYear());
Field yearEstimateField = PotentialCustomerHeadData.class.getDeclaredField("yearEstimate");
yearEstimateField.setAccessible(true);
ExcelProperty excel = yearEstimateField.getAnnotation(ExcelProperty.class);
InvocationHandler excelH = Proxy.getInvocationHandler(excel);
// 获取 AnnotationInvocationHandler 的 memberValues 字段
Field excelF = excelH.getClass().getDeclaredField("memberValues");
excelF.setAccessible(true);
Map excelValues = (Map) excelF.get(excelH);
excelValues.put("value", new String[]{"项目利润", String.format("%s预估\n(万元/年)", year)});
WriteSheet potentialCustomerSheet = EasyExcel.writerSheet(index, sheetNameEnum.getName()).head(PotentialCustomerHeadData.class).build();
合并单元格

刚好一个表单导出的时候,需要实现单元格合并,实现AbstractMergeStrategy类的方法,具体合并策略根据业务需求实现。

//策略类
public class CellMergeStrategy extends AbstractMergeStrategy {
    private Map<String, List<RowRange>> strategyMap;
    private Sheet sheet;

    public CellMergeStrategy() {
    }

    public CellMergeStrategy(Map<String, List<RowRange>> strategyMap) {
        this.strategyMap = strategyMap;
    }

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {
        this.sheet = sheet;
        if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
            /**
             * 保证每个cell被合并一次,如果不加上面的判断,因为是一个cell一个cell操作的,
             * 例如合并A2:A3,当cell为A2时,合并A2,A3,但是当cell为A3时,又是合并A2,A3,
             * 但此时A2,A3已经是合并的单元格了
             */
            for (Map.Entry<String, List<RowRange>> entry : strategyMap.entrySet()) {
                int columnIndex = Integer.parseInt(entry.getKey());
                entry.getValue().forEach(rowRange -> {
                    //添加一个合并请求
                    sheet.addMergedRegionUnsafe(new CellRangeAddress(rowRange.getStart(),
                            rowRange.getEnd(), columnIndex, columnIndex));
                });
            }
        }
    }
}
/**
 * Excel工具类
 */
public class ExcelUtil {
    //获取需要合并的单元格
    public static Map<String, List<RowRange>> getProfitReachedMergeStrategy(List<ProfitReachedHeadData> profitReachedHeadDataList) {
        Map<String, List<RowRange>> strategyMap = new HashMap<>();
        ProfitReachedHeadData previousData = null;
        int size = profitReachedHeadDataList.size();
        for (int i = 0; i < size; i++) {
            ProfitReachedHeadData currentData = profitReachedHeadDataList.get(i);
            if (previousData != null) {
                if (currentData.getDeptName().equals(previousData.getDeptName())) {
                    fillStrategyMap(strategyMap, "0", i);
                }
                if (currentData.getOrgName().equals(previousData.getOrgName())) {
                    fillStrategyMap(strategyMap, "1", i);
                }
            }
            previousData = currentData;
        }
        return strategyMap;
    }
    
    /**
     * 增加合并策略
     * @param strategyMap   Map<String, List<RowRange>>
     * @param key           String
     * @param index         int
     */
    private static void fillStrategyMap(Map<String, List<RowRange>> strategyMap, String key, int index) {
        List<RowRange> rowRangeList = strategyMap.get(key) == null ? new ArrayList<>() : strategyMap.get(key);
        boolean flag = false;
        for (RowRange rowRange : rowRangeList) {
            //分段list中是否有end索引是上一行索引的,如果有,则索引+1
            if (rowRange.getEnd() == index) {
                rowRange.setEnd(index + 1);
                flag = true;
            }
        }
        //如果没有,则新增分段
        if (!flag) {
            rowRangeList.add(new RowRange(index, index + 1));
        }
        strategyMap.put(key, rowRangeList);
    }
    
    public class RowRange {
        private int start;
        private int end;
	}
}
//业务实现
 List<ProfitReachedHeadData> profitSummaryHeadDataList = profitSummaryService.buildProfitReachedHeadDataList(entry.getValue());
Map<String, List<RowRange>> summaryStrategyMap = ExcelUtil.getProfitReachedMergeStrategy(profitSummaryHeadDataList);
WriteSheet profitSummarySheet = EasyExcel.writerSheet(index, String.format("%s-%s合计-%s月", sheetNameEnum.getName(),permissionOperate.getDeptName(),entry.getKey().substring(5))).registerWriteHandler(new CellMergeStrategy(summaryStrategyMap)).head(ProfitReachedHeadData.class).build();
excelWriter.write(profitSummaryHeadDataList, profitSummarySheet);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用EasyExcel导出数据的步骤如下: 1. 首先,确保已经将EasyExcel的依赖添加到项目中。可以在项目的pom.xml文件中添加以下依赖: ``` <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.11</version> </dependency> ``` 2. 创建一个实体类来表示导出数据。这个实体类中的字段将对应Excel表格中的列。 3. 在代码中,使用EasyExcel提供的API来进行数据导出。首先,创建一个`ExcelWriter`对象,指定导出的文件路径和文件名。然后,使用`Sheet`和`Row`对象来指定要导出数据所在的Sheet和行。接下来,通过设置每个单元格的值,将数据写入到Excel表格中。最后,调用`finish`方法来完成导出操作。 下面是一个示例代码,演示了如何使用EasyExcel导出数据: ```java // 1. 创建导出数据实体类 public class User { private String name; private int age; // 其他字段... // 省略构造方法、getter和setter } // 2. 导出数据 public void exportData() { // 2.1 创建ExcelWriter对象 String fileName = "导出文件.xlsx"; ExcelWriter excelWriter = EasyExcel.write(fileName).build(); // 2.2 创建Sheet对象 Sheet sheet = new Sheet(1, 0, User.class); sheet.setSheetName("用户数据"); // 2.3 查询数据库或准备数据列表 List<User> userList = userService.getUserList(); // 2.4 写入数据到Excel表格中 excelWriter.write(userList, sheet); // 2.5 完成导出操作 excelWriter.finish(); } ``` 这样,使用EasyExcel就可以轻松地将数据导出到Excel表格中了。通过设置`User`类中的字段,可以控制导出表格的列名和数据内容。 请注意,上述示例代码中的`userService.getUserList()`是一个示例方法,用于获取要导出数据列表。具体的获取数据的方式可能因项目而异。 参考资料:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值