簡介
我們知道最簡單的導出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模板
這是一個樣例模板
下載下來會發現, 里面有一些黃色的標記就是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