一、概述
Apache POI 简介是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能。
二、依赖
org.apache.poi
poi
4.1.0
org.apache.poi
poi-scratchpad
4.1.0
org.apache.poi
poi-ooxml
4.1.0
org.apache.poi
poi-ooxml-schemas
4.1.0
org.apache.poi
poi-excelant
4.1.0
三、核心类
1. XSSFWorkbook:工作簿,代表整个excel
常用方法 | 说明 |
---|---|
XSSFWorkbook() | 从头开始创建一个新的XSSFworkbook对象。 |
XSSFWorkbook(java.io.File file) | 通过给定的文件,构造XSSFWorkbook对象。 |
XSSFWorkbook(java.io.InputStream is) | 构造一个XSSFWorkbook对象,通过缓冲整个输入流到内存中,然后为它打开一个OPCPackage对象。 |
XSSFWorkbook(java.lang.String path) | 通过文件的路径,构建一个的XSSFWorkbook对象。 |
2. Sheet:sheet页
常用方法 | 说明 |
---|---|
workBook.createSheet(String var1) | 创建sheet页 |
workBook.getNumberOfSheets() | 获取sheet页数量 |
workBook.getSheetAt(int var1) | 获取第n个sheet页 |
workBook.getSheet(String var1) | 获取名称为var1的sheet页 |
3. Row:行
常用方法 | 说明 |
---|---|
sheet.createRow(int var1) | 创建第n行 |
sheet.getRow(int var1) | 获取第n行 |
sheet.removeRow(Row var1) | 删除行 |
4. Cell:单元格
常用方法 | 说明 |
---|---|
row.createCell(int var1) | 在一行上第n个位置创建单元格 |
row.getCell(int var1) | 获取一行上第n个单元格 |
cell.setCellValue(String var1) | 赋值 |
cell.setCellValue(double var1) | 赋值 |
cell.setCellValue(Date var1) | 赋值 |
cell.setCellStyle(CellStyle var1) | 设置样式 |
cell.setCellType(CellType var1) | 设置数据格式(CellType是一个枚举,常用的有STRING字符串、NUMERIC整数小数日期) |
String getStringCellValue() | 取值 |
Date getDateCellValue() | 取值 |
double getNumericCellValue() | 取值 |
5. CellStyle:样式
// 创建样式
XSSFCellStyle cellStyle = workbook.createCellStyle();
// 设置边框
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
// 水平居中、垂直居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 自动换行
cellStyle.setWrapText(true);
// 设置背景色填充模式及颜色
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
// 设置单元格格式:日期格式
XSSFDataFormat format= workbook.createDataFormat();
dateStyle.setDataFormat(format.getFormat("yyyy/MM/dd"));
// 设置单元格格式:文本
// XSSFDataFormat format = xssfWorkbook.createDataFormat();
// cellStyle.setDataFormat(format.getFormat("@"));
// 设置字体 颜色、字体、大小
Font font = workbook.createFont();
font.setColor(IndexedColors.RED.index);
font.setFontName("宋体");
font.setFontHeightInPoints((short) 10);
cellStyle.setFont(font);
6.其他
// 合并单元格
CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
sheet.addMergedRegion(region);
注:还有许多重要的方法,可以到类里进行查看。
四、几个典型的应用场景
1.导入
// excel行数据对应的实体类
public class PersonExcel {
private String name;
private String sexStr;
private double height;
private double weight;
private Date birthday;
......
......
}
// 读取excel中的数据
private List importExcel(String filepath) throws Exception {
List excelList = new ArrayList<>();
// 1.获取文件
filepath = filepath.replaceAll("/", "\\\\");
if (filepath == "false") {
this.ajaxReturn(1, "请上传正确的文件类型");
}
File file = new File(filepath);
String ext = filepath.substring(filepath.lastIndexOf("."));
FileInputStream fis = null;
Workbook workBook = null;
if (file.exists()) {
try {
// 2.创建workBook对象
fis = new FileInputStream(file);
try {
if (".xls".equals(ext)) {
workBook = new HSSFWorkbook(fis);
} else if (".xlsx".equals(ext)) {
workBook = new XSSFWorkbook(fis);
} else if (".xlsm".equals(ext)) {
workBook = new XSSFWorkbook(fis);
}
} catch (Exception ex) {
workBook = new HSSFWorkbook(fis);
}
// 3.获取数据
// A.获取sheet表个数
int numberOfSheets = workBook.getNumberOfSheets();
// B.依次对每个sheets处理
for (int s = 0; s < numberOfSheets; s++) {
Sheet sheetAt = workBook.getSheetAt(s);
//获取工作表名称
String sheetName = sheetAt.getSheetName();
// 获取当前Sheet的总行数
int rowsOfSheet = sheetAt.getPhysicalNumberOfRows();
int coloumNum = sheetAt.getRow(0).getPhysicalNumberOfCells();//获得总列数
// C.读取第一行,即标题行
Row row0 = sheetAt.getRow(0);
int physicalNumberOfCells = sheetAt.getRow(0).getPhysicalNumberOfCells();
// excel第一行的标题,即列名称
String[] title = new String[physicalNumberOfCells];
for (int i = 0; i < physicalNumberOfCells; i++) {
title[i] = row0.getCell(i).getStringCellValue();
}
// D.读取下面的数据
for (int r = 1; r < rowsOfSheet; r++) {
Row row = sheetAt.getRow(r);
if (row == null) {
continue;
} else {
PersonExcel excel = new PersonExcel();
// 总列(格)
for (int i = 0; i < coloumNum; i++) {
switch (title[i]) {
case "姓名":
if (row.getCell(i) != null) {
excel.setName(row.getCell(i).getStringCellValue().trim());
} else {
excel.setName("");
}
continue;
case "性别":
if (row.getCell(i) != null) {
excel.setSexStr(row.getCell(i).getStringCellValue().trim());
} else {
excel.setSexStr("");
}
continue;
case "身高(cm)":
if (row.getCell(i) != null) {
excel.setHeight(row.getCell(i).getNumericCellValue());
} else {
excel.setHeight(0);
}
continue;
case "体重(kg)":
if (row.getCell(i) != null) {
excel.setWeight(row.getCell(i).getNumericCellValue());
} else {
excel.setWeight(0);
}
continue;
case "出生日期":
if (row.getCell(i) != null) {
excel.setBirthday(row.getCell(i).getDateCellValue());
} else {
excel.setBirthday(null);
}
continue;
}
}
excelList.add(excel);
}
}
}
if (fis != null) {
fis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("文件不存在!");
}
return excelList;
}
2.导出
// 1.获取需要输出为excel的数据(这里简化操作,手动造数据)
List personList = new ArrayList<>();
PersonExcel person1 = new PersonExcel("张三", "男", 175.4, 60.3, DateUtil.parse("1998/5/5", "yyyy/MM/dd"));
PersonExcel person2 = new PersonExcel("李四", "女", 155, 45.7, DateUtil.parse("1994/5/5", "yyyy/MM/dd"));
PersonExcel person3 = new PersonExcel("王五", "男", 133, 33, DateUtil.parse("2010/5/5", "yyyy/MM/dd"));
personList.add(person1);
personList.add(person2);
personList.add(person3);
// 2.创建workbook以及sheet页
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("sheet1");
// 3.样式
// 表头样式:边框及底部颜色
XSSFCellStyle headStyle = workbook.createCellStyle();
headStyle.setBorderBottom(BorderStyle.THIN);
headStyle.setBorderLeft(BorderStyle.THIN);
headStyle.setBorderRight(BorderStyle.THIN);
headStyle.setBorderTop(BorderStyle.THIN);
headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
// 数据行样式:边框
XSSFCellStyle bodyStyle = workbook.createCellStyle();
bodyStyle.setBorderBottom(BorderStyle.THIN);
bodyStyle.setBorderLeft(BorderStyle.THIN);
bodyStyle.setBorderRight(BorderStyle.THIN);
bodyStyle.setBorderTop(BorderStyle.THIN);
// 特殊单元格,日期格式
XSSFCellStyle dateStyle = workbook.createCellStyle();
dateStyle.setBorderBottom(BorderStyle.THIN);
dateStyle.setBorderLeft(BorderStyle.THIN);
dateStyle.setBorderRight(BorderStyle.THIN);
dateStyle.setBorderTop(BorderStyle.THIN);
XSSFDataFormat format = workbook.createDataFormat();
dateStyle.setDataFormat(format.getFormat("yyyy/MM/dd"));
// 4.表头:文本以及宽度
String[] headers = {"姓名", "性别", "身高(cm)", "体重(kg)", "出生日期"};
int[] widths = {3000, 3000, 3000, 3000, 5000};
// 写入表头
XSSFRow row = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
sheet.setColumnWidth(i, widths[i]);
XSSFCell cell = row.createCell(i);
XSSFRichTextString text = new XSSFRichTextString(headers[i]);
cell.setCellValue(text);
// 样式
cell.getCellStyle().setAlignment(HorizontalAlignment.CENTER);
cell.getCellStyle().setVerticalAlignment(VerticalAlignment.CENTER);
cell.setCellStyle(headStyle);
}
// 5.写入数据
for (int i = 0; i < personList.size(); i++) {
// 创建行并写入数据
XSSFRow rowObj = sheet.createRow(i + 1);
rowObj.createCell(0).setCellValue(personList.get(i).getName());
rowObj.createCell(1).setCellValue(personList.get(i).getSexStr());
rowObj.createCell(2).setCellValue(personList.get(i).getHeight());
rowObj.createCell(3).setCellValue(personList.get(i).getWeight());
rowObj.createCell(4).setCellValue(personList.get(i).getBirthday());
// 设置样式
for (int j = 0; j <= 4; j++) {
if (j != 4) {
rowObj.getCell(j).setCellStyle(bodyStyle);
} else {
rowObj.getCell(j).setCellStyle(dateStyle);
}
}
// 设置单元格类型,方便导出后再导入
rowObj.getCell(2).setCellType(CellType.NUMERIC);
rowObj.getCell(3).setCellType(CellType.NUMERIC);
rowObj.getCell(4).setCellType(CellType.NUMERIC);
}
有不足之处,望留言指出!萌新上路,请多多指教。