Java导出Excel

简介

我们知道最简单的导出excel的方式其实是导出csv, 例如dbv的导出功能就是导出csv, 非常的傻瓜方便, 也不需要引入依赖, 但是当导出的文件内容中含有 "," (逗号)时, 文件的格式就乱了. 效果不好.
​Java 导出 Excel的轮子还是挺多的, 有些也非常简单易用, 下面就简单叙述下

Apache poi

官方文档 https://poi.apache.org/components/spreadsheet/quick-guide.html
生成Excel的方式是通过Java代码, 例子如

Workbook wb = new XSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(0);
row.createCell(0).setCellValue(" \uD83D\uDE0E \uD83D\uDE00 ☺ \uD83D\uDC7D");
row.createCell(1).setCellValue(1.2);
// 创建一个富文本 ,设定一下颜色
RichTextString rx = createHelper.createRichTextString("特殊表情来了");
XSSFFont font = (XSSFFont) wb.createFont();
font.setColor(new XSSFColor(new java.awt.Color(0, 255, 0)));
//
rx.applyFont(font);
row.createCell(2).setCellValue(rx);
row.createCell(3).setCellValue(true);

// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xlsx")) {
    wb.write(fileOut);
}

可以看到, 基本上是通过手撸代码的方式 , 颗粒度比较细, 但还是非常的繁琐, 每一行的创建都需要手撸, 样式什么的统统得用代码来控制, 量还是比较大的

测试的时候, 发现使用xlsx 格式导出的时候 ,如果使用emoji, 生成的excel中emoji会变成??, 而使用xls格式的时候就不会, 看了下源码, 应该是 HSSFRichTextString 这个类在转化的时候正确处理的emoji, 而生成xlsx的 XSSFRichTextString 没有正确处理

JXL (Java Excel API)

这个文档已经比较老了 , https://www.teamdev.com/downloads/jexcel/docs/JExcel-PGuide.html

乍一看, 最近一次的更新也是2011年的时候了, 用法其实和上面的类似, 也是通过手撸代码, 并且不支持xlsx类型, 所以不推荐使用了, (既然要手撸代码, 为啥不选择poi呢?)

@Test
public void javaExcelTest() throws Exception {
    // 类似, 构建一个xls文件
    WritableWorkbook wworkbook = jxl.Workbook.createWorkbook(new File("output.xls"));
    WritableSheet wsheet = wworkbook.createSheet("First Sheet", 0);
    // 在某个单元格创建, 下标从0开始
    Label label = new Label(0, 2, "A label record");   // 即 单元格 A3
    wsheet.addCell(label);
    Number number = new Number(3, 4, 3.1459);      //单元格 D5
    wsheet.addCell(number);
    wworkbook.write();
    wworkbook.close();

    jxl.Workbook workbook = jxl.Workbook.getWorkbook(new File("output.xls"));
    jxl.Sheet sheet = workbook.getSheet(0);
    Cell cell1 = sheet.getCell(0, 2);
    System.out.println(cell1.getContents());
    Cell cell2 = sheet.getCell(3, 4);
    System.out.println(cell2.getContents());
    workbook.close();
}

JXLS2

官网上JXLS的文档例子比较详细, 有时间的话可以读一下

如果不想看英文的, 可以看这个中文文档, 比较新

乍一看这个和上面那个很像, 但是可以说是非常不一样了, 同时JXLS2 和 JXLS1 使用方式还是有很大的区别, 这里就只讲述JXLS2的使用方式

JXLS2和上面的编码方式最大的不同就是可以使用模板, 废话少说, 直接步入正题

步骤

1.引入依赖

<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-poi</artifactId>
    <version>1.0.15</version>
</dependency>
<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-reader</artifactId>
    <version>2.0.3</version>
</dependency>

2.导入excel模板

这是一个样例模板1534298389935

下载链接

下载下来会发现, 里面有一些黄色的标记就是JXLS用来生成数据指令, 下面这段话比较关键
jx:area(lastCell="D4")

作用是从打上批注的这行单元格开始, 到 lastCell 所在的单元格区域, 是需要转化的矩形区域, 即我们的模板数据, 就必须写在这个区域内

下面这行数据使用了 jxls的 each指令

jx:each(items="employees" var="employee" lastCell="D4")

3. 编写代码

按照上面定义好模板后 ,生成的代码就非常简单, 可以看到

@Test
public void t() throws Exception {
	//构造需要填充的数据
    List<Employee> employees = new ArrayList<>();
    employees.add(new Employee().setName("jack").setBirthDate(new Date()).setPayment(BigDecimal.valueOf(System.currentTimeMillis())));
    employees.add(new Employee().setName("wuli").setBirthDate(new Date()).setPayment(BigDecimal.valueOf(System.currentTimeMillis())));
    employees.add(new Employee().setName("fiefei").setBirthDate(new Date().setPayment(BigDecimal.valueOf(System.currentTimeMillis())));
    employees.add(new Employee().setName("keai").setBirthDate(new Date()).setPayment(BigDecimal.valueOf(System.currentTimeMillis())));

    try (InputStream is = ExportExcelTest.class.getResourceAsStream("/object_collection_template.xls")) {
        try (OutputStream os = new FileOutputStream("target/object_collection_output.xls")) {
            Context context = new Context();
			// 放入上下文
            context.putVar("employees", employees);
            JxlsHelper.getInstance().processTemplate(is, os, context);
        }
    }
}

其他的方式也有, 例如不需要写批注, 可以使用xml来编写,但是试了一下,发现有点繁琐,, 不如这种简便,
无一例外, 都需要事先准备好一个excel模板, 如果有复杂的生成要求, 可以下载对照官网例子来实现

https://bitbucket.org/leonate/jxls-demo/downloads/?tab=downloads

posted @ 2018-09-19 09:41  hinsy  阅读(1382)  评论(0编辑  收藏  举报