Xử lý và chỉnh sửa tệp Excel bằng Java POI

Để 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;
    }
}
  1. Đọ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);
        }

    }

}
  1. Á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ố

  2. 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);


  1. 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();
    }

}

Thẻ: Java poi Excel Apache POI xử lý tệp

Đăng vào ngày 19 tháng 6 lúc 20:11