Để sử dụng Apache POI, cần thêm các thư viện sau vào dự án:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
1. Kiểm tra loại tệp trước khi xử lý
Trước khi xử lý tệp Excel với POI, cần xác định xem tệp có phải là tệp Excel hợp lệ hay không.
Lý do cần kiểm tra: POI chỉ hỗ trợ xử lý các tệp có định dạng .xlsx hoặc .xls. Nếu truyền tệp không phải kiểu Excel vào, dòng mã XSSFWorkbook workbook = new XSSFWorkbook(is); sẽ ném ra ngoại lệ NotOfficeXmlFileException.
Ngoại lệ này thuộc nhóm RuntimeException, nên cần được tránh trong lập trình thay vì bắt và xử lý.
Cách xác định loại tệp: Trong phiên bản POI từ 3.17 trở lên, lớp FileMagic cung cấp phương thức kiểm tra loại tệp.
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.poifs.filesystem.FileMagic;
public class ExcelUtil {
public static Boolean isValidExcelFile(InputStream input) throws IOException {
Boolean result = false;
FileMagic magic = FileMagic.valueOf(input);
if (magic.equals(FileMagic.OOXML)) { // XLSX
result = true;
} else if (magic.equals(FileMagic.OLE2)) {// XLS
result = true;
}
return result;
}
}
- Đọc nội dung tệp Excel
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExcelReader {
Logger logger = LoggerFactory.getLogger(ExcelReader.class);
@Test
public void readExcelFile() {
try {
String path = "C:\\test\\test.xlsx";
InputStream stream = new BufferedInputStream(new FileInputStream(path));
if (ExcelUtil.isValidExcelFile(stream)) {
XSSFWorkbook workbook = new XSSFWorkbook(stream);
Sheet sheet = workbook.getSheetAt(0);
Map<String, String> dataMap = new HashMap<>();
logger.info("Số lượng hàng trong sheet là: " + sheet.getLastRowNum());
for (int index = 0; index < sheet.getLastRowNum(); index++) {
Row row = sheet.getRow(index);
Cell cellA = row.getCell(0);
Cell cellB = row.getCell(1);
logger.info("Giá trị ô A: " + cellA.getStringCellValue().trim());
logger.info("Giá trị ô B: " + cellB.getStringCellValue().trim());
dataMap.put(row.getCell(3).getStringCellValue().trim(), row.getCell(0).getStringCellValue().trim());
}
stream.close();
} else {
logger.error("Tệp không phải là tệp Excel: " + path);
}
} catch (IOException e) {
logger.error("Lỗi khi đọc tệp: ", e);
}
}
}
-
Áp dụng định dạng cho ô: thiết lập viền, căn giữa, định dạng ngày tháng và số
-
Thêm một hàng mới: Di chuyển các hàng từ vị trí bắt đầu đến cuối xuống dưới một hàng, sau đó tạo hàng mới tại vị trí trống để chèn dữ liệu.
Tham khảo phương thức shiftRows trong POI
// Di chuyển các hàng từ startRow đến endRow xuống n hàng
void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight);
// Tạo một hàng mới tại vị trí rownum
Row createRow(int rownum);
- Gộp ô:
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
Tham khảo cách gộp ô trong POI
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelProcessor {
private static String fileLocation = "C:/TEST/test.xlsx";
public static void main(String[] args) {
try {
updateExcel(fileLocation);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void updateExcel(String filePath) throws IOException {
InputStream input = new FileInputStream(filePath);
XSSFWorkbook wb = new XSSFWorkbook(input);
Sheet sheet = wb.getSheetAt(0);
System.out.println(sheet.getLastRowNum());
// 1. Cập nhật giá trị ô trong sheet
for (int i = 0; i < sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
for (Cell cell : row) {
if ("field_reference".equals(cell.getStringCellValue().trim())) {
cell.setCellValue("fff");
} else if ("field_credit_date".equals(cell.getStringCellValue().trim())) {
cell.setCellValue("ff2020/2/30 12:45");
}
}
}
// 2.1 Định dạng ô: viền
CellStyle style1 = wb.createCellStyle();
style1.setBorderBottom(BorderStyle.THIN);
style1.setBorderLeft(BorderStyle.THIN);
style1.setBorderRight(BorderStyle.THIN);
style1.setBorderBottom(BorderStyle.THIN);
Cell cell1 = sheet.getRow(10).getCell(0);
cell1.setCellValue("cell1");
cell1.setCellStyle(style1);
// 2.2 Định dạng ô: căn giữa
CellStyle style2 = wb.createCellStyle();
style2.setAlignment(HorizontalAlignment.CENTER);
style2.setVerticalAlignment(VerticalAlignment.CENTER);
Cell cell2 = sheet.getRow(11).getCell(0);
cell2.setCellValue("cell2");
cell2.setCellStyle(style2);
// 2.3 Định dạng ô: định dạng số
DataFormat numFormat = wb.createDataFormat();
CellStyle style3 = wb.createCellStyle();
style3.setDataFormat(numFormat.getFormat("#,##0.00"));
Cell cell3 = sheet.getRow(12).getCell(0);
cell3.setCellValue(300000002);
cell3.setCellStyle(style3);
// 2.4 Định dạng ô: định dạng ngày tháng
DataFormat dateFormat = wb.createDataFormat();
CellStyle style4 = wb.createCellStyle();
style4.setDataFormat(dateFormat.getFormat("yyyy-MM-dd"));
Cell cell4 = sheet.getRow(13).getCell(0);
cell4.setCellValue(new Date());
cell4.setCellStyle(style4);
// 3. Chèn hàng mới bằng shiftRows() và createRow()
// Lặp 3 lần để chèn 3 hàng
for (int i = 0; i < 3; i++) {
sheet.shiftRows(5, sheet.getLastRowNum() + i, 1, true, false);
Row newRow = sheet.createRow(5);
Cell cell01 = newRow.createCell(0);
cell01.setCellValue("aaa");
Cell cell02 = newRow.createCell(1);
cell02.setCellValue("bbb");
Cell cell03 = newRow.createCell(2);
Cell cell04 = newRow.createCell(3);
// 4. Gộp ô: Gộp cột 2 đến 4 ở hàng 5
CellRangeAddress region = new CellRangeAddress(5, 5, 1, 3);
sheet.addMergedRegion(region);
}
OutputStream output = new FileOutputStream(filePath);
wb.write(output);
output.flush();
output.close();
input.close();
}
}