整理一篇poi对Excel的常用读写操作,方便以后作为参考。
读取
创建测试Excel如下:
image.png
第一步创建workbook
File file = new File("D:" + File.separator + "test.xlsx");
// 天才第一步,雀氏……啊呸,第一步创建workbook
Workbook workbook = WorkbookFactory.create(file);
第二步获取sheet
// 获取sheet,这个0取决于要读取的是第几个sheet,正常来说都取的是第一个sheet
Sheet sheet = workbook.getSheetAt(0);
第三步获取自己要的信息
获取行号
// 获取第一行的行号
int firstRowNum = sheet.getFirstRowNum();
System.out.println("第一行:" + firstRowNum);
// 获取最后一行的行号
int lastRowNum = sheet.getLastRowNum();
System.out.println("最后一行:" + lastRowNum);
输出结果:
第一行:0
最后一行:2
第一行指Excel开始的非空行,最后一行指Excel结束的非空行。
遍历Excel
// 遍历Excel
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
System.out.println("当前行:" + cell.getRowIndex() +
"\t当前列:" + cell.getColumnIndex() +
"\t当前值:" + cell.getStringCellValue());
}
}
输出结果:
当前行:0 当前列:0 当前值:表头A列
当前行:0 当前列:1 当前值:表头B列
当前行:0 当前列:2 当前值:表头C列
当前行:1 当前列:0 当前值:第1行A列
当前行:1 当前列:1 当前值:第1行B列
当前行:1 当前列:2 当前值:第1行C列
当前行:3 当前列:0 当前值:第2行A列
当前行:3 当前列:1 当前值:第2行B列
当前行:3 当前列:2 当前值:第2行C列
或者也可以使用for循环进行遍历:
Excel改为:
image.png
// 遍历Excel
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
for (int r = firstRowNum; r <= lastRowNum; r++) {
Row row = sheet.getRow(r);
if (null == row) {
System.out.println("当前行:" + r + " 为空行");
continue;
}
short firstCellNum = row.getFirstCellNum();
short lastCellNum = row.getLastCellNum();
for (short c = firstCellNum; c < lastCellNum; c++) {
Cell cell = row.getCell(c);
if (null == cell) {
System.out.println("当前单元格:" + r + ":" + c + " 为空");
continue;
}
System.out.println("当前行:" + r +
"\t当前列:" + c +
"\t当前值:" + cell.getStringCellValue());
}
}
使用fori循环需要注意两点:
- 注意判空;
- lastRowNum等于最后一行,所以用小于等于;lastCellNum等于最后一行加一,所以要用小于。
输出结果:
当前行:0 当前列:0 当前值:表头A列
当前行:0 当前列:1 当前值:表头B列
当前行:0 当前列:2 当前值:
当前行:0 当前列:3 当前值:表头C列
当前行:1 当前列:0 当前值:第1行A列
当前行:1 当前列:1 当前值:第1行B列
当前单元格:1:2 为空
当前行:1 当前列:3 当前值:第1行C列
当前行:2 为空行
当前行:3 当前列:0 当前值:第2行A列
当前行:3 当前列:1 当前值:第2行B列
当前单元格:3:2 为空
当前行:3 当前列:3 当前值:第2行C列
写入
第一步创建workbook
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(null, 1, true);
构造器中的第二个参数是默认初始化条数,这里测试就写1了。
创建sheet、row、cell
Sheet sheet = sxssfWorkbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
第三步写入信息
最基本的写入信息
cell.setCellValue("测试内容");
结果:
image.png
设置表格对齐格式
CellStyle cellStyle = sxssfWorkbook.createCellStyle();
// 设置水平对齐
cellStyle.setAlignment(HorizontalAlignment.CENTER);
// 设置垂直对齐
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置单元格内自动换行
cellStyle.setWrapText(true);
cell.setCellStyle(cellStyle);
cell.setCellValue("测试内容测试内容测试内容测试内容测试内容");
结果:
image.png
设置字体
CellStyle cellStyle = sxssfWorkbook.createCellStyle();
Font font = sxssfWorkbook.createFont();
// 设置字体大小
font.setFontHeightInPoints((short)20);
// 设置字体颜色
font.setColor(Font.COLOR_RED);
// 设置粗体
font.setBold(true);
// 设置斜体
font.setItalic(true);
// 设置删除线
font.setStrikeout(true);
// 设置字体(运行程序的机器上一定要有这个字体)
font.setFontName("楷体");
cellStyle.setFont(font);
cell.setCellStyle(cellStyle);
cell.setCellValue("测试内容");
结果:
image.png
合并单元格
CellRangeAddress region = new CellRangeAddress(0, 0, 0, 1);
sheet.addMergedRegion(region);
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("测试内容");
CellRangeAddress
构造器的四个参数就是要合并单元格的4个坐标,依次是:开始行、结束行、开始列、结束列。是一个闭区间。
一个sheet可以通过addMergedRegion()
添加多个合并单元格。
结果:
使用合并单元格也需要注意一点。比如我这里合并了第0行的第0、1列,那么我要在第0行或者第1行的2列写入东西时,都是
createCell(2)
,也就是说,合并单元格不影响cell的rowIndex和columnIndex。
日常的Excel操作,这些基本就够用了。哪里需要有改动再举一反三吧。最后贴一个将Excel写入文件的代码:
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
sxssfWorkbook.write(outputStream);
outputStream.flush();
sxssfWorkbook.dispose();
} catch (IOException e) {
System.out.println("输出异常:" + e.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
System.out.println("关闭输出流异常");
}
}
}
网友评论