一种操作复杂样式Excel的思路

作者 : 开心源码 本文共4462个字,预计阅读时间需要12分钟 发布时间: 2022-05-12 共91人阅读

基于 上一篇 提到的想法,今天抽了时间实现出来了。

先贴截图。

运行结果

个人觉得填充底色,合并单元格,各种设置格式之流的操作用纯代码来实现还是蛮耗费精力的。但是,假如是基于下面这样已经调好格式的模板,只要要往里填充数据的话,工作量要小很多。

模板

模板通过2个sheet拼接完成。代码填充好第一个sheet的数据之后,再把第二个sheet的内容拷贝到第一个sheet的最后。

数据是通过POJO和自己设置注解配合完成的。目前注解主要用于取得单元格所对应的行,后期还会增加其余属性。时间关系,POJO的属性暂时也只支持了String一种类型。

注解定义如下:

/** * @author nathan * @date 2019/3/24 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface ExcelProperties {    int index();}

一个示例POJO如下:

/** * @author nathan * @date 2019/3/24 */@Getter@Setterpublic class FooDTO {    @ExcelProperties(index = 0)    private String empty1;    @ExcelProperties(index = 1)    private String busiName;    @ExcelProperties(index = 2)    private String busiType;    @ExcelProperties(index = 3)    private String empty2;    @ExcelProperties(index = 4)    private String value1;    @ExcelProperties(index = 5)    private String value2;    @ExcelProperties(index = 6)    private String empty3;}

一个可以运行的Demo:

/** * @author nathan * @date 2019/3/24 */public class RptUtil {    public static void main(String[] args) {        // 从第1行,第4列开始,客户指定        int startRow = 0;        int startCol = 4;        List<FooDTO> foos = getFooList();        int sheet2StartRow = 1;        int sheet2StartCol = 2;        File template = new File("/tmp/template.xlsx");        File output = new File("/tmp/test.xlsx");        // 从template文件读取2个sheet        // sheet1从第0行,第4列开始插入数据        // sheet2从第1行,第2列开始读取        write(template, output, foos, startRow, startCol, true, sheet2StartRow, sheet2StartCol);    }    private static List<FooDTO> getFooList() {        FooDTO foo1 = new FooDTO();        foo1.setBusiName("测试名称1");        foo1.setBusiType("测试类型1");        foo1.setValue1("50.12");        foo1.setValue2("12.86");        return Lists.newArrayList(foo1);    }    public static <T> void write(File template, File output, List<T> data, int startRow, int startCol, boolean copySheet2, int sheet2StartRow, int sheet2StartCol) {        FileInputStream in = null;        FileOutputStream out = null;        try {            in = new FileInputStream(template);            XSSFWorkbook source = new XSSFWorkbook(in);            // 取得sheet1的内容            XSSFSheet sheet1 = source.getSheetAt(0);            // 插入主体数据1            insertData(data, sheet1, startRow, startCol);            if (copySheet2) {                copyFromSheet2(source, sheet1, startCol + data.size() - sheet2StartCol, sheet2StartRow, sheet2StartCol);            }            // 写入到output            out = new FileOutputStream(output);            source.write(out);        } catch (Exception e) {            e.printStackTrace();        } finally {            close(in);            close(out);        }    }    /**     * 关闭资源     *     * @param closeable     */    private static void close(Closeable closeable) {        if(closeable != null) {            try {                closeable.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    /**     * 插入数据(List形式)     *     * @param data     * @param sheet     * @param startRow     * @param startCol     * @param <T>     * @throws Exception     */    private static <T> void insertData(List<T> data, XSSFSheet sheet, int startRow, int startCol) throws Exception {        for (T t : data) {            insertOne(t, sheet, startRow, startCol);            startCol++;        }    }    /**     * 插入数据(单条)     *     * @param data     * @param sheet     * @param startRow     * @param startCol     * @param <T>     * @throws Exception     */    private static <T> void insertOne(T data, XSSFSheet sheet, int startRow, int startCol) throws Exception {        XSSFCell cell;        XSSFRow row;        for (Field field : data.getClass().getDeclaredFields()) {            int index = -1;            String value = "";            if (field.isAnnotationPresent(ExcelProperties.class)) {                ExcelProperties props = field.getAnnotation(ExcelProperties.class);                field.setAccessible(true);                if (field.getGenericType().toString().equals("class java.lang.String")) {                    String name = field.getName();                    name = name.substring(0, 1).toUpperCase() + name.substring(1);                    Method m = data.getClass().getMethod("get" + name);                    String val = (String) m.invoke(data);                    index = props.index();                    value = val;                }            }            if (index != -1) {                row = sheet.getRow(startRow + index);                // 找到最后一个cell                Cell lastCell = row.getCell(row.getLastCellNum() - 1);                // 创立一个cell                cell = row.createCell(startCol);                // 拷贝样式                cell.setCellStyle(lastCell.getCellStyle());                // 设置值                cell.setCellValue(value);            }        }    }    /**     * 把sheet2的内容拷贝到sheet1     *     * @param source     * @param sheet     * @param startCol     * @param sheet2StartRow     * @param sheet2StartCol     */    private static void copyFromSheet2(XSSFWorkbook source, XSSFSheet sheet, int startCol, int sheet2StartRow, int sheet2StartCol) {        // 从sheet2取得剩余部分内容,并插入到sheet1        XSSFCell cell;        XSSFRow row;        // 插入sheet2的内容        XSSFSheet sheet2 = source.getSheetAt(1);        Iterator<Row> iterator = sheet2.iterator();        // 跳过若干行        while (sheet2StartRow > 1) {            iterator.next();            sheet2StartRow--;        }        int count = 0;        while (iterator.hasNext()) {            XSSFRow current = (XSSFRow) iterator.next();            row = sheet.getRow(count);            for (int j = sheet2StartCol; j < current.getLastCellNum(); j++) {                cell = row.createCell(startCol + j);                cell.copyCellFrom(current.getCell(j), new CellCopyPolicy());            }            count++;        }        // 删除sheet2        source.removeSheetAt(1);    }}

maven依赖:

<dependency>    <groupId>org.apache.poi</groupId>    <artifactId>poi</artifactId>    <version>4.0.1</version></dependency><dependency>    <groupId>org.apache.poi</groupId>    <artifactId>poi-ooxml</artifactId>    <version>3.17</version></dependency><dependency>    <groupId>org.apache.poi</groupId>    <artifactId>poi-ooxml</artifactId>    <version>3.17</version></dependency>

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 一种操作复杂样式Excel的思路

发表回复