通用的excel导出工具roy-poi

作者: staconfree | 来源:发表于2018-10-20 17:02 被阅读1次

需求背景

开发中经常会碰到导出excel的需求,通常导出的格式大部分都是“表头+循环数据+表尾”的形式,其中可能还包含字体大小颜色,边框,背景颜色,合并单元格等场景。

分析

初级的开发者可能会想到用poi根据实际需求去实现,然后一个格子一个格子的去设置格式和填数据再导出,这种方式只适合应付单个导出需求,当多个导出需求时弊端明显。

可能有人会使用alibaba的EasyExcel来处理导出,他的思路是使用对象注解的形势去设置每个单元格的格式,但是我觉得这种方式也不够简便

我的实现思路

类似于写页面一样,先定好模板,然后填数。

1、使用excel先画好一个模板,模板中写入一些变量和个性化标签。

2、首次导出的时候,系统会读取模板内容(包括样式,数据等),并将模板信息以结构化的形式缓存在内存中。

3、读取业务数据,按模板的格式填充数据自动进行导出。

核心代码

参考 com.staconfree.poi.write.sxssf.TestParser

String templateFilePath = "D://template.xlsx";
String exportFilePath = "D://export.xlsx";
SxssfExcelParser excelParse = new SxssfExcelParser(templateFilePath, exportFilePath);
Map<String,Object> dataStack = getBizData();// 此处获取业务代码
 excelParse.setTemplateSheetName("会员报表");
 excelParse.parse(dataStack);
 excelParse.endSheet();
 excelParse.setTemplateSheetName("机型报表");
 excelParse.parse(dataStack);
 excelParse.endSheet();
 excelParse.flush();

演示效果

运行源码中的TestParser,(ps:第一次导出由于要读模板和反射数据对象,所以比较慢,之后这些数据都会缓存就不会慢了)

会在 roy-poi/target/test-classes/ 下看到两个文件 template.xlsx 和 test_parser.xlsx 。

  • 前者是模板文件(是我们事先做好的),如下:

    image.png
    image.png
上面关键的模板格式解释:
一、
$$BEGINLOOP{"name":"brandList","mergedbaseon":[[1,2,3],[4]]}
代表循环brandList对象,后面 mergedbaseon 的含义是,如果相邻两行的1,2,3列数据完全相同,则这三列相邻的数据自动合并单元格,
同理相邻两行的第4列如果相同,则第四列相邻相同的数据也自动合并单元格
二、
${#index+1} 代表循环体下标+1
三、
$$yyyy-$$MM-$$dd $$HH:$$mm:$$ss 自动打印系统时间
  • 后者是导出文件,如下:

    image.png
    image.png


从效果中可以看到,导出的格式跟模板格式一模一样,细看导出代码,可以发现预留了WriteCallBack接口,可以对导出的每个单元格做个性化的设置,如上面的合计那行做了横向的合并单元格

如何使用

clone 代码下来,运行 clean install -Dmaven.test.skip 得到jar包 roy-poi-1.0.0.jar

然后以springboot工程为例,先将roy-poi-1.0.0.jar 文件放到工程下的lib文件夹,然后在pom文件中加入如下配置:

    <dependency>
        <groupId>roy.poi</groupId>
        <artifactId>poi</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${basedir}/lib/roy-poi-1.0.0.jar</systemPath>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.8</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-codec</artifactId>
                <groupId>commons-codec</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.8</version>
    </dependency>
    <dependency>
        <groupId>net.sf.json-lib</groupId>
        <artifactId>json-lib</artifactId>
        <version>2.2.3</version>
        <classifier>jdk15</classifier>
    </dependency>
    <dependency>
        <groupId>com.esotericsoftware.reflectasm</groupId>
        <artifactId>reflectasm</artifactId>
        <version>1.05</version>
    </dependency>

这样就可以了,但是由于springboot工程打包出来的是个jar包,一般我们会把模板也打包到jar包里,但是由于程序无法读取jar里面的模板,所以如果你的工程是springboot工程的话,需要先把jar包里面的模板使用io流的方式先复制到外面的文件夹,然后才可以使用上面的导出功能。

可以参考如下的copyFileOutJar方法:

public class FileUtil {
    private static Map<String,Boolean> fileExists = new HashMap<>();

    public static void copyFileOutJar(String srcClassPathFile, String targetFile) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(srcClassPathFile);
        InputStream inputStream = classPathResource.getInputStream();
        File xslt = createFile(targetFile);
        try {
            FileUtils.copyInputStreamToFile(inputStream, xslt);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    //  创建临时文件
    private static File createFile(String targetFile) throws IOException{
        File file = new File(targetFile);
        String filePath = targetFile.substring(0,targetFile.lastIndexOf("/"));
        if(!fileExists.containsKey(filePath) || !file.exists()){
            File dir = new File(filePath);
            if(!dir.exists() && !dir.isDirectory()){
                dir.mkdir();
            }
            file.createNewFile();
            fileExists.put(targetFile,true);
        }
        return file;
    }
}

附录

源代码地址:roy-poi,这是本人开源的第一个项目(ps:功能很简单的小项目~~),以后有时间会再开源一些,欢迎关注,一起学习探讨。

相关文章

网友评论

    本文标题:通用的excel导出工具roy-poi

    本文链接:https://www.haomeiwen.com/subject/hfemzftx.html