Apache POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目,该项目提供了很多简单易用的api,针对不同类型的文档进行了封装,操作十分简单。
- HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
- XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
- HWPF - 提供读写Microsoft Word DOC97格式档案的功能。
- XWPF - 提供读写Microsoft Word DOC2003格式档案的功能。
- HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
- HDGF - 提供读Microsoft Visio格式档案的功能。
- HPBF - 提供读Microsoft Publisher格式档案的功能。
- HSMF - 提供读Microsoft Outlook格式档案的功能。
实际开发中我们用的最多的应该是Excel文档的操作,以下提供简单的读写示例:
- 写操作:
public abstract class ExcelUtil {
public static CellStyle createHeaderStyle(Workbook workbook) {
//通过CellStyle定义表格样式
CellStyle cellStyle = workbook.createCellStyle();
//字体设置
Font font = workbook.createFont();
font.setBold(true);
font.setFontName("宋体");
font.setFontHeightInPoints((short) 10);// 设置字体大小
cellStyle.setFont(font);
//对单元格边框定义
cellStyle.setBorderBottom(BorderStyle.THIN);// 下边框
cellStyle.setBorderLeft(BorderStyle.THIN);// 左边框
cellStyle.setBorderTop(BorderStyle.THIN);//上边框
cellStyle.setBorderRight(BorderStyle.THIN);//有边框
cellStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
return cellStyle;
}
/**
* 定义文本样式
*
* @param workbook
*/
public static CellStyle createBodyStyle(Workbook workbook) {
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 10);
cellStyle.setFont(font);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.LEFT);
return cellStyle;
}
/**
* 生成表格
*
* @param modelList 导出实体,包含表头信息
*/
public static Workbook generateTable(List<ExcelTextModel> modelList) {
if (CollectionUtils.isEmpty(modelList)) {
return null;
}
Workbook workbook = new HSSFWorkbook();
//生成表格
//官方建议在应用样式时,应该一次性获取样式,而不应该在循环创建实际表格内容时每次都生成一个样式对象
CellStyle headerStyle = createHeaderStyle(workbook);
CellStyle bodyStyle = createBodyStyle(workbook);
Sheet sheet = workbook.createSheet();
for (ExcelTextModel excelTextModel : modelList) {
int rowIndex = excelTextModel.getRowIndex();
Row row = sheet.createRow(rowIndex);
Map<Integer, String> cellMap = excelTextModel.getCell();
for (Integer cellIndex : cellMap.keySet()) {
Cell cell = row.createCell(cellIndex);
cell.setCellValue(cellMap.get(cellIndex));
if (rowIndex == 0) {
cell.setCellStyle(headerStyle);
} else {
cell.setCellStyle(bodyStyle);
}
}
}
return workbook;
}
/**
* 生成表格
*
* @param headModel 表头
* @param modelList 内容
*/
public static Workbook generateTable(ExcelTextModel headModel, List<ExcelTextModel> modelList) {
if (headModel != null) {
modelList.add(headModel);
}
return generateTable(modelList);
}
}
- 单元测试:
@Test
public void testCreateWorkBook() throws IOException {
List<ExcelTextModel> excelTextModels = new ArrayList<>();
//创建表资源
List<User> userList = userService.findAll();//通过数据库获取用户信息
for (int i = 0; i < userList.size(); i++) {
User user = userList.get(i);
ExcelTextModel model = new ExcelTextModel();
model.setRowIndex(i + 1);
Map<Integer, String> cell = new HashMap<>();
cell.put(0, user.getId());
cell.put(1, user.getUsername());
cell.put(2, user.getPassword());
model.setCell(cell);
excelTextModels.add(model);
}
//创建表头
ExcelTextModel header = new ExcelTextModel();
header.setRowIndex(0);
Map<Integer, String> headerCell = new HashMap<>();
headerCell.put(0, "索引");
headerCell.put(1, "账号");
headerCell.put(2, "密码");
header.setCell(headerCell);
Workbook workbook = ExcelUtil.generateTable(header, excelTextModels);
//保存文件
FileOutputStream fileOutputStream = new FileOutputStream("F:\\demo.xls");
workbook.write(fileOutputStream);
}
- 读操作:
这里的读操作相对较简单,只做了读取的动作并打印出读取的内容,开发中可以根据具体的情况封装操作。
/**
* 读取excel
* @throws IOException
*/
@Test
public void testReadExcel() throws IOException {
//通过输入流方式构建一个Workbook对象,后面的读操作实际就是写操作的逆向操作
FileInputStream fileInputStream = new FileInputStream("F:\\demo.xls");
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(fileInputStream);
Workbook workbook = new HSSFWorkbook(poifsFileSystem);
int index = workbook.getActiveSheetIndex();
Sheet sheet = workbook.getSheetAt(index);
//此处应注意获取最后一行内容和最后一列内容,他们在最后一个索引上面存在差异
int lastRowNum = sheet.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
short lastCellNum = row.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = row.getCell(j);
System.out.print(cell.getStringCellValue()+" ");
}
System.out.println();
}
}
- 此外,poi还提供了很多工具类用以辅助操作表格,比如对单元格数据类型的定义操作。
- 因为excel目前存在两种格式(.xlsx,.xls),官方文档推荐使用兼容格式创建Workbook对象,根据不同后缀名去读和写操作,大家也可以参考官方文档操作,此处就不过多说明。