目录
- 概述
- Excel 的两种形式
- POI
- 操作
- 创建 Excel
- 创建单元格
- 设置格式
- 绘制图形
- 加载 Excel
- 模版打印
概述
在企业级应用开发中,Excel 报表是一种最常见的报表需求,Excel 报表开发一般分为两种形式:
- 方便操作,基于 Excel 的报表批量上传数据
- 通过 java 代码生成 Excel 报表
Excel 的两种形式
目前世面上的 Excel 分为两个大的版本 Excel2003 和 Excel2007 及以上两个版本,两者之间的区别如下:
| Excel 2003 | Excel 2003 |
---|
后缀 | xls | xlsx |
结构 | 二进制格式,核心结构是复合文档类型的结构 | XML 类型结构 |
单 sheet 数据量 | 行:65535 列:256 | 行:1048576 列:16384 |
特点 | 存储容量优先 | 基于xml 压缩,占用空间小、操作效率高 |
✨Java 中常见的用来操作 Excl 的方式一般有 2 种:JXL 和 POI
- JXL 只能对 Excel 进行操作,属于比较老的框架,它只支持到 Excel 95-2000 的版本。现在已经停止更新和维护。
- POI 是 apache 的项目,可对微软的 Word、Excel、PPT 进行操作,包括 office2003 和 2007,Excel2003 和 2007
POI
APache POI 是 Apache 软件基金会的开源项目,由 Java 编写的免费开源的跨平台的 Java API,Apache POI 提供 API 给 Java 语言操作Microsoft Office
功能
✨应用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <dependencies> <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>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.0.1</version> </dependency> </dependencies>
|
结构说明
结构 | 对应的 office |
---|
HSSF | 提供读写 Microsoft Excel XLS 格式档案的功能 |
XSSF | 提供读写 Microsoft Excel OOXML XLSX 格式档案的功能 |
HWPF | 提供读写 Microsoft Word DOC 格式档案的功能 |
HSLF | 提供读写 Microsoft PowerPoint 格式档案的功能 |
HDGF | 提供读 Microsoft Visio 格式档案的功能 |
HPBF | 提供读 Microsoft Publisher 格式档案的功能 |
HSMF | 提供读 Microsoft Outlook 格式档案的功能 |
操作
API 名称 | 含义 |
---|
Workbook | Excel 的文档对象,针对不同的 Excel 类型分为:HSSFWorkbook(2003)和 XSSFWorkbool(2007) |
Sheet | Excel 的表单 |
Row | Excel 的行 |
Cell | Excel 的格子单元 |
Font | Excel 字体 |
CellStyle | 格子单元样式 |
创建 Excel
1 2 3 4 5
| XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet("test"); FileOutputStream fileOutputStream = new FileOutputStream("test.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close();
|
创建单元格
1 2 3 4 5 6 7 8
| XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet("test"); XSSFRow row = sheet.createRow(3); XSSFCell cell = row.createCell(0); cell.setCellValue("Hello World"); FileOutputStream fileOutputStream = new FileOutputStream("test.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close();
|
设置格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| XSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.DASH_DOT);
cellStyle.setBorderBottom(BorderStyle.HAIR);
Font font = workbook.createFont();
font.setFontName("仿宋");
font.setFontHeightInPoints((short) 28); cellStyle.setFont(font);
sheet.setColumnWidth(0,31*256);
row.setHeightInPoints(50);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cell.setCellStyle(cellStyle);
CellRangeAddress region = new CellRangeAddress(0, 3, 0, 3); sheet.addMergedRegion(region); fileOutputStream.close();
|
绘制图形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet("test");
FileInputStream fileInputStream = new FileInputStream("/Users/humingchao/IdeaProjects/SaaS_ihrm/poiTest/p1.jpg"); byte[] bytes = IOUtils.toByteArray(fileInputStream); fileInputStream.read(bytes);
int index = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
XSSFCreationHelper helper = workbook.getCreationHelper();
Drawing<?> patriarch = sheet.createDrawingPatriarch();
ClientAnchor anchor = helper.createClientAnchor();
anchor.setRow1(0);
anchor.setCol1(0);
Picture picture = patriarch.createPicture(anchor, index); picture.resize();
FileOutputStream fileOutputStream = new FileOutputStream("test3.xlsx");
workbook.write(fileOutputStream); fileOutputStream.close();
|
加载 Excel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| public static void main(String[] args) throws Exception { XSSFWorkbook workbook = new XSSFWorkbook("demo.xlsx"); Sheet sheet = workbook.getSheetAt(0);
int totalRowNum = sheet.getLastRowNum();
Row row = null; Cell cell = null;
for (int rowNum = 0; rowNum <=sheet.getLastRowNum(); rowNum++) { row = sheet.getRow(rowNum); StringBuilder stringBuilder = new StringBuilder(); for (int cellNum = 2; cellNum < row.getLastCellNum(); cellNum++) { cell = row.getCell(cellNum); stringBuilder.append(getValue(cell)).append("-"); } System.out.println(stringBuilder.toString()); } }
public static Object getValue(Cell cell) { Object value = null; switch (cell.getCellType()) { case STRING: value = cell.getStringCellValue(); break; case BOOLEAN: value = cell.getBooleanCellValue(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { value = cell.getDateCellValue(); } else { value = cell.getNumericCellValue(); } break; case FORMULA: value = cell.getCellFormula(); break; default: break; } return value; }
|
模版打印
自定义生成 Excel 报表文件还是有很多不尽如意的地方,特别是针对复杂报表头,单元格样式,字体等操作。手写这些代码不仅费时费力,有时候效果还不太理想。
❓ 那怎么样才能更方便的对报表样式,报表头进行处理呢?
答案是使用已经准备好的 Excel 模板,只需要关注模板中的数据即可
⛵ 模版打印的操作步骤
- 制作模版文件(模版文件的路径)
- 导入(加载)模版文件,从而得到一个工作簿
- 读取工作表
- 读取行
- 读取单元格
- 读取单元格样式
- 设置单元格内容
- 其他单元格就可以使用读到的样式了