Lucrul cu Microsoft Excel în Java

1. Introducere

În acest tutorial, vom demonstra utilizarea API-urilor Apache POI și JExcel pentru lucrul cu foi de calcul Excel .

Ambele biblioteci pot fi utilizate pentru a citi, scrie și modifica dinamic conținutul unei foi de calcul Excel și oferă o modalitate eficientă de integrare a Microsoft Excel într-o aplicație Java.

2. Dependențele Maven

Pentru început, va trebui să adăugăm următoarele fișiere în fișierul nostru pom.xml :

 org.apache.poi poi 3.15   org.apache.poi poi-ooxml 3.15 

Cele mai recente versiuni ale poi-ooxml și jxls-jexcel pot fi descărcate de la Maven Central.

3. Apache POI

Biblioteca Apache POI acceptă atât fișiere .xls cât și .xlsx și este o bibliotecă mai complexă decât alte biblioteci Java pentru lucrul cu fișiere Excel.

Acesta oferă interfața Workbook pentru modelarea unui fișier Excel și interfețele Sheet , Row și Cell care modelează elementele unui fișier Excel, precum și implementări ale fiecărei interfețe pentru ambele formate de fișier.

Atunci când se lucrează cu mai nou .xlsx formatul de fișier, ar trebui să utilizați XSSFWorkbook, XSSFSheet, XSSFRow și XSSFCell clase .

Pentru a lucra cu mai vechi .xls format, utilizați HSSFWorkbook, HSSFSheet, HSSFRow, și HSSFCell clase .

3.1. Citind din Excel

Să creăm o metodă care deschide un fișier .xlsx , apoi citește conținutul din prima foaie a fișierului.

Metoda de citire a conținutului celulei variază în funcție de tipul datelor din celulă. Tipul conținutului celulei poate fi determinat folosind metoda getCellTypeEnum () a interfeței Cell .

Mai întâi, să deschidem fișierul dintr-o anumită locație:

FileInputStream file = new FileInputStream(new File(fileLocation)); Workbook workbook = new XSSFWorkbook(file);

Apoi, să recuperăm prima foaie a fișierului și să repetăm ​​fiecare rând:

Sheet sheet = workbook.getSheetAt(0); Map
    
      data = new HashMap(); int i = 0; for (Row row : sheet) { data.put(i, new ArrayList()); for (Cell cell : row) { switch (cell.getCellTypeEnum()) { case STRING: ... break; case NUMERIC: ... break; case BOOLEAN: ... break; case FORMULA: ... break; default: data.get(new Integer(i)).add(" "); } } i++; }
    

Apache POI are metode diferite pentru citirea fiecărui tip de date. Să extindem conținutul fiecărui caz de comutare de mai sus.

Când valoarea enum de tip de celulă este STRING , conținutul va fi citit folosind metoda getRichStringCellValue () a interfeței Cell :

data.get(new Integer(i)).add(cell.getRichStringCellValue().getString());

Celulele cu tip de conținut NUMERIC pot conține fie o dată, fie un număr și sunt citite în modul următor:

if (DateUtil.isCellDateFormatted(cell)) { data.get(i).add(cell.getDateCellValue() + ""); } else { data.get(i).add(cell.getNumericCellValue() + ""); }

Pentru valorile BOOLEAN , avem metoda getBooleanCellValue () :

data.get(i).add(cell.getBooleanCellValue() + "");

Și când tipul de celulă este FORMULA , putem folosi metoda getCellFormula () :

data.get(i).add(cell.getCellFormula() + "");

3.2. Scrierea în Excel

Apache POI folosește aceleași interfețe prezentate în secțiunea anterioară pentru scrierea într-un fișier Excel și are un suport mai bun pentru stil decât JExcel.

Să creăm o metodă care scrie o listă de persoane pe o foaie intitulată „Persoane” . Mai întâi, vom crea și stiliza un rând de antet care conține celule „Nume” și „Vârstă” :

Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Persons"); sheet.setColumnWidth(0, 6000); sheet.setColumnWidth(1, 4000); Row header = sheet.createRow(0); CellStyle headerStyle = workbook.createCellStyle(); headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); XSSFFont font = ((XSSFWorkbook) workbook).createFont(); font.setFontName("Arial"); font.setFontHeightInPoints((short) 16); font.setBold(true); headerStyle.setFont(font); Cell headerCell = header.createCell(0); headerCell.setCellValue("Name"); headerCell.setCellStyle(headerStyle); headerCell = header.createCell(1); headerCell.setCellValue("Age"); headerCell.setCellStyle(headerStyle);

În continuare, să scriem conținutul tabelului cu un stil diferit:

CellStyle style = workbook.createCellStyle(); style.setWrapText(true); Row row = sheet.createRow(2); Cell cell = row.createCell(0); cell.setCellValue("John Smith"); cell.setCellStyle(style); cell = row.createCell(1); cell.setCellValue(20); cell.setCellStyle(style);

În cele din urmă, să scriem conținutul într-un fișier „temp.xlsx” din directorul curent și să închidem registrul de lucru:

File currDir = new File("."); String path = currDir.getAbsolutePath(); String fileLocation = path.substring(0, path.length() - 1) + "temp.xlsx"; FileOutputStream outputStream = new FileOutputStream(fileLocation); workbook.write(outputStream); workbook.close();

Să testăm metodele de mai sus într-un test JUnit care scrie conținut în fișierul temp.xlsx, apoi citește același fișier pentru a verifica dacă conține textul pe care l-am scris:

public class ExcelTest { private ExcelPOIHelper excelPOIHelper; private static String FILE_NAME = "temp.xlsx"; private String fileLocation; @Before public void generateExcelFile() throws IOException { File currDir = new File("."); String path = currDir.getAbsolutePath(); fileLocation = path.substring(0, path.length() - 1) + FILE_NAME; excelPOIHelper = new ExcelPOIHelper(); excelPOIHelper.writeExcel(); } @Test public void whenParsingPOIExcelFile_thenCorrect() throws IOException { Map
    
      data = excelPOIHelper.readExcel(fileLocation); assertEquals("Name", data.get(0).get(0)); assertEquals("Age", data.get(0).get(1)); assertEquals("John Smith", data.get(1).get(0)); assertEquals("20", data.get(1).get(1)); } }
    

4. JExcel

Biblioteca JExcel este o bibliotecă ușoară având avantajul că este mai ușor de utilizat decât Apache POI, dar cu dezavantajul că oferă suport doar pentru procesarea fișierelor Excel în format .xls (1997-2003).

În acest moment, fișierele .xlsx nu sunt acceptate.

4.1. Citind din Excel

Pentru a lucra cu fișiere Excel, această bibliotecă oferă o serie de clase care reprezintă diferitele părți ale unui fișier Excel. Workbook clasă reprezintă întreaga colecție de foi. Sheet clasă reprezintă o singură foaie, iar celula clasa reprezintă o singură celulă a unei foi de calcul.

Let's write a method that creates a workbook from a specified Excel file, gets the first sheet of the file, then traverses its content and adds each row in a HashMap:

public class JExcelHelper { public Map
    
      readJExcel(String fileLocation) throws IOException, BiffException { Map
     
       data = new HashMap(); Workbook workbook = Workbook.getWorkbook(new File(fileLocation)); Sheet sheet = workbook.getSheet(0); int rows = sheet.getRows(); int columns = sheet.getColumns(); for (int i = 0; i < rows; i++) { data.put(i, new ArrayList()); for (int j = 0; j < columns; j++) { data.get(i) .add(sheet.getCell(j, i) .getContents()); } } return data; } }
     
    

4.2. Writing to Excel

For writing to an Excel file, the JExcel library offers classes similar to the ones used above, that model a spreadsheet file: WritableWorkbook, WritableSheet, and WritableCell.

The WritableCell class has subclasses corresponding to the different types of content that can be written: Label, DateTime, Number, Boolean, Blank, and Formula.

This library also provides support for basic formattings, such as controlling font, color and cell width.

Let's write a method that creates a workbook called ‘temp.xls' in the current directory, then writes the same content we wrote in the Apache POI section.

First, let's create the workbook:

File currDir = new File("."); String path = currDir.getAbsolutePath(); String fileLocation = path.substring(0, path.length() - 1) + "temp.xls"; WritableWorkbook workbook = Workbook.createWorkbook(new File(fileLocation));

Next, let's create the first sheet and write the header of the excel file, containing “Name” and “Age” cells:

WritableSheet sheet = workbook.createSheet("Sheet 1", 0); WritableCellFormat headerFormat = new WritableCellFormat(); WritableFont font = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD); headerFormat.setFont(font); headerFormat.setBackground(Colour.LIGHT_BLUE); headerFormat.setWrap(true); Label headerLabel = new Label(0, 0, "Name", headerFormat); sheet.setColumnView(0, 60); sheet.addCell(headerLabel); headerLabel = new Label(1, 0, "Age", headerFormat); sheet.setColumnView(0, 40); sheet.addCell(headerLabel);

With a new style, let's write the content of the table we've created:

WritableCellFormat cellFormat = new WritableCellFormat(); cellFormat.setWrap(true); Label cellLabel = new Label(0, 2, "John Smith", cellFormat); sheet.addCell(cellLabel); Number cellNumber = new Number(1, 2, 20, cellFormat); sheet.addCell(cellNumber);

It's very important to remember to write to the file and close it at the end so it can be used by other processes, using the write() and close() methods of Workbook class:

workbook.write(); workbook.close();

5. Concluzie

Acest tutorial a ilustrat cum se utilizează API-ul Apache POI și API-ul JExcel pentru a citi și scrie un fișier Excel dintr-un program Java.

Codul sursă complet pentru acest articol poate fi găsit în proiectul GitHub.