12/08/2018, 14:40

Thao tác với file excel trong Java sử dụng API Apache POI

Đôi điều về Apache POI Nhiều khi trong một ứng dụng phần mềm cần thiết phải tạo ra các báo cáo trong định dạng file Microsoft Excel, hoặc sẽ nhận file Excel như dữ liệu đầu vào. Ví dụ, một ứng dụng được phát triển cho bộ phận Tài chính của một công ty sẽ được yêu cầu để tạo ra tất cả các kết quả ...

Đôi điều về Apache POI

Nhiều khi trong một ứng dụng phần mềm cần thiết phải tạo ra các báo cáo trong định dạng file Microsoft Excel, hoặc sẽ nhận file Excel như dữ liệu đầu vào. Ví dụ, một ứng dụng được phát triển cho bộ phận Tài chính của một công ty sẽ được yêu cầu để tạo ra tất cả các kết quả đầu ra là file Excel. Bất kỳ lập trình viên Java nào muốn sản xuất các tập tin MS Office như đầu ra thì nên sử dụng một giao diện lập trình(API) để làm như vậy. Apache POI là một API cho phép lập trình viên tạo mới, sửa và hiển thị Microsoft Office file sử dụng Java. Apache POI là một thư viện mã nguồn mở được phát triển và xuất bản bởi Apache Software Foundation.

Cấu phần của Apache POI

Apache POI chứa các lớp và phương thức để làm việc trên các tài liệu dưới định dạng file MS Office. Danh sách các thành phần của API như sau.

POIFS (Poor Obfuscation Implementation File System) : This component is the basic factor of all other POI elements. It is used to read different files explicitly.

HSSF (Horrible Spreadsheet Format) : Được sử dụng để đọc ghi định dạng .xls của file MS-Excel.

XSSF (XML Spreadsheet Format) : Được sử dụng để đọc ghi định dạng .xlsx của file MS-Excel.

HPSF (Horrible Property Set Format) : Được sử dụng để trích xuất các thuộc tính của file MS-Office.

HWPF (Horrible Word Processor Format) : Được sử dụng để đọc ghi định dạng .doc của file MS-Office.

XWPF (XML Word Processor Format) : Được sử dụng để đọc ghi định dạng .docx của file MS-Office.

HSLF (Horrible Slide Layout Format) : Được sử dụng để đọc ghi file PowerPoint.

HDGF (Horrible DiaGram Format) : Được sử dụng cho file MS-Visio dưới dạng binary.

HPBF (Horrible PuBlisher Format) : Được sử dụng để đọc ghi file MS-Publisher.

Note

Các phiên bản cũ của Apache POI chỉ hỗ trợ các định dạng file binary như doc, xls, ppt, vv từ phiên bản 3.5 trở đi, POI hỗ trợ các định dạng file OOXML của MS-Office như docx, xlsx, pptx, vv

Làm việc với MS-Excel

Excel là định dạng file rất phổ biến được tạo bởi Microsoft. Mặc dù nó không phải là định dạng file mở nhưng ứng dụng Java vẫn có thể đọc, ghi Excel file bằng cách sử dụng giao diện lập trình Apache POI.

  1. Cách thức lấy thư viện Apache POI Để sử dụng POI cho ứng dụng của bạn, có 2 cách:
  • Cho ứng dụng không sử dụng Maven: Tải về thư viện tại đây: Apache POI Giải nén zip file và thêm các JAR file sau khi giải nén vào classpath ứng dụng của bạn: Nếu chỉ thao tác với định dạng file Excel 2003(.xls), chỉ cần file poi-VERSION.jar Nếu cần thao tác với định dạng file Excel 2007(.xlsx), thì bạn cần thêm các file jar bên dưới nữa: poi-ooxml-VERSION.jar poi-ooxml-schemas-VERSION.jar xmlbeans-VERSION.jar commons-collections-VERSION.jar

  • Cho ứng dụng Maven: Thêm các dependency sau vào file pom.xml:

Excel 2003(.xls): <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>VERSION</version> </dependency>

Excel 2007(.xlsx): <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>VERSION</version> </dependency>

  1. Thao tác với file Excel Để làm việc với Excel bạn cần phải hiểu 4 interfaces dưới đây: Workbook: Đại diện cho 1 Excel workbook. HSSFWorkbook sử dụng cho định dạng .xls và XSSFWorkbook sử dụng cho định dạng .xlsx Sheet: Đại diện cho 1 Excel worksheet. Row: Đại diện cho 1 dòng trong 1 spreadsheet. Cell: Đại diện cho 1 cell trong 1 dòng.

Sau đây là ví dụ đọc ghi excel đơn giản, trên thực tế các bạn có thể ứng dụng API với rất nhiều các tính năng khác

Ta có file excel như sau:

Chúng ta sẽ sử dụng entity Book để đọc ghi dữ liệu

package vuta.apache.poi.example;

public class Book {
    private String title;
    private String author;
    private double price;
 
    public Book() {
    }
 
    public Book(String title, String author, double price) {
		super();
		this.title = title;
		this.author = author;
		this.price = price;
	}

	public String toString() {
        return String.format("%s - %s - %f", title, author, price);
    }

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}
 
    
}

Lớp SimpleExcelReader sẽ đọc dữ liệu từ file excel

package vuta.apache.poi.example;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class SimpleExcelReader {

    public static void main(String[] args) throws IOException {
	    String excelFilePath = "E:/VuTA_Software/Books.xls";
	    SimpleExcelReader reader = new SimpleExcelReader();
	    List<Book> listBooks = reader.readBooksFromExcelFile(excelFilePath);
	    System.out.println(listBooks);
	}

	private Object getCellValue(Cell cell) {
	    switch (cell.getCellType()) {
	    case Cell.CELL_TYPE_STRING:
	        return cell.getStringCellValue();
	 
	    case Cell.CELL_TYPE_BOOLEAN:
	        return cell.getBooleanCellValue();
	 
	    case Cell.CELL_TYPE_NUMERIC:
	        return cell.getNumericCellValue();
	    }
	 
	    return null;
	}
	
	public List<Book> readBooksFromExcelFile(String excelFilePath) throws IOException {
	    List<Book> listBooks = new ArrayList<>();
	    FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
	 
	    Workbook workbook = getWorkbook(inputStream, excelFilePath);
	    Sheet firstSheet = workbook.getSheetAt(0);
	    Iterator<Row> iterator = firstSheet.iterator();
	 
	    while (iterator.hasNext()) {
	        Row nextRow = iterator.next();
	        Iterator<Cell> cellIterator = nextRow.cellIterator();
	        Book aBook = new Book();
	 
	        while (cellIterator.hasNext()) {
	            Cell nextCell = cellIterator.next();
	            int columnIndex = nextCell.getColumnIndex();
	 
	            switch (columnIndex) {
	            case 1:
	                aBook.setTitle((String) getCellValue(nextCell));
	                break;
	            case 2:
	                aBook.setAuthor((String) getCellValue(nextCell));
	                break;
	            case 3:
	                aBook.setPrice((double) getCellValue(nextCell));
	                break;
	            }
	 
	 
	        }
	        listBooks.add(aBook);
	    }
	 
	    workbook.close();
	    inputStream.close();
	 
	    return listBooks;
	}
	
    //Được sử dụng để có thể đọc được cả định dạng .xls và xlsx
	private Workbook getWorkbook(FileInputStream inputStream, String excelFilePath)
	        throws IOException {
	    Workbook workbook = null;
	 
	    if (excelFilePath.endsWith("xlsx")) {
	        workbook = new XSSFWorkbook(inputStream);
	    } else if (excelFilePath.endsWith("xls")) {
	        workbook = new HSSFWorkbook(inputStream);
	    } else {
	        throw new IllegalArgumentException("The specified file is not Excel file");
	    }
	 
	    return workbook;
	}
}

Lớp SimpleExcelWriter sẽ ghi dữ liệu ra 1 file excel

package vuta.apache.poi.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class SimpleExcelWriter {

	public static void main(String[] args) {
		
		SimpleExcelWriter excelWriter = new SimpleExcelWriter();
		 
		List<Book> listBook = excelWriter.getListBook();
		String excelFilePath = "E:/VuTA_Software/NiceJavaBooks.xls";
		 
		try {
			excelWriter.writeExcel(listBook, excelFilePath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private Workbook getWorkbook(String excelFilePath)
	        throws IOException {
	    Workbook workbook = null;
	 
	    if (excelFilePath.endsWith("xlsx")) {
	        workbook = new XSSFWorkbook();
	    } else if (excelFilePath.endsWith("xls")) {
	        workbook = new HSSFWorkbook();
	    } else {
	        throw new IllegalArgumentException("The specified file is not Excel file");
	    }
	 
	    return workbook;
	}
	
	public void writeExcel(List<Book> listBook, String excelFilePath) throws IOException {
	    Workbook workbook = getWorkbook(excelFilePath);
	    Sheet sheet = workbook.createSheet();
	    createHeaderRow(sheet);
	    int rowCount = 0;
	 
	    for (Book aBook : listBook) {
	        Row row = sheet.createRow(++rowCount);
	        writeBook(aBook, row);
	    }
	 
	    try (FileOutputStream outputStream = new FileOutputStream(excelFilePath)) {
	        workbook.write(outputStream);
	    }
	}
	
	private void writeBook(Book aBook, Row row) {
	    Cell cell = row.createCell(1);
	    cell.setCellValue(aBook.getTitle());
	 
	    cell = row.createCell(2);
	    cell.setCellValue(aBook.getAuthor());
	 
	    cell = row.createCell(3);
	    cell.setCellValue(aBook.getPrice());
	}
	
    //Có thể format được như in đậm, set font
	private void createHeaderRow(Sheet sheet) {
		 
	    CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
	    Font font = sheet.getWorkbook().createFont();
	    font.setBold(true);
	    font.setFontHeightInPoints((short) 16);
	    cellStyle.setFont(font);
	 
	    Row row = sheet.createRow(0);
	    Cell cellTitle = row.createCell(1);
	 
	    cellTitle.setCellStyle(cellStyle);
	    cellTitle.setCellValue("Title");
	 
	    Cell cellAuthor = row.createCell(2);
	    cellAuthor.setCellStyle(cellStyle);
	    cellAuthor.setCellValue("Author");
	 
	    Cell cellPrice = row.createCell(3);
	    cellPrice.setCellStyle(cellStyle);
	    cellPrice.setCellValue("Price");
	}
	
	private List<Book> getListBook() {
	    Book book1 = new Book("Head First Java", "Kathy Serria", 79);
	    Book book2 = new Book("Effective Java", "Joshua Bloch", 36);
	    Book book3 = new Book("Clean Code", "Robert Martin", 42);
	    Book book4 = new Book("Thinking in Java", "Bruce Eckel", 35);
	 
	    List<Book> listBook = Arrays.asList(book1, book2, book3, book4);
	 
	    return listBook;
	}

}

Trên đây là ví dụ rất cơ bản về đọc ghi excel. Trong thực tế các bạn có thể ứng dụng được rất nhiều tính năng nâng cao nhờ vào Apache POI, và không chỉ dừng lại với Excel. Mong rằng bài viết này sẽ hữu ích cho các bạn. Xin cảm ơn các bạn đã theo dõi bài viết.

0