Lavorare con Microsoft Excel in Java

1. Introduzione

In questo tutorial, dimostreremo l'uso del POI Apache e delle API JExcel per lavorare con i fogli di calcolo Excel .

Entrambe le librerie possono essere utilizzate per leggere, scrivere e modificare dinamicamente il contenuto di un foglio di calcolo Excel e fornire un modo efficace per integrare Microsoft Excel in un'applicazione Java.

2. Dipendenze di Maven

Per iniziare, dovremo aggiungere le seguenti dipendenze al nostro file pom.xml :

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

Le ultime versioni di poi-ooxml e jxls-jexcel possono essere scaricate da Maven Central.

3. Apache POI

La libreria POI di Apache supporta sia file .xls che .xlsx ed è una libreria più complessa rispetto ad altre librerie Java per lavorare con file Excel.

Fornisce l' interfaccia della cartella di lavoro per modellare un file Excel e le interfacce Foglio , Riga e Cella che modellano gli elementi di un file Excel, nonché le implementazioni di ciascuna interfaccia per entrambi i formati di file.

Quando si lavora con il più recente .xlsx formato di file, è necessario utilizzare i XSSFWorkbook, XSSFSheet, XSSFRow e XSSFCell classi .

Per lavorare con il più vecchio .xls format, utilizzare i HSSFWorkbook, HSSFSheet, HSSFRow, e HSSFCell classi .

3.1. Leggere da Excel

Creiamo un metodo che apra un file .xlsx , quindi legga il contenuto dal primo foglio del file.

Il metodo per leggere il contenuto della cella varia a seconda del tipo di dati nella cella. Il tipo di contenuto della cella può essere determinato utilizzando il metodo getCellTypeEnum () dell'interfaccia Cell .

Innanzitutto, apriamo il file da una determinata posizione:

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

Successivamente, recuperiamo il primo foglio del file e iteriamo su ogni riga:

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 ha metodi diversi per leggere ogni tipo di dati. Espandiamo il contenuto di ogni caso di switch sopra.

Quando il valore dell'enumerazione del tipo di cella è STRING , il contenuto verrà letto utilizzando il metodo getRichStringCellValue () dell'interfaccia della cella :

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

Le celle con il tipo di contenuto NUMERICO possono contenere una data o un numero e vengono lette nel modo seguente:

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

Per BOOLEANI valori, abbiamo la getBooleanCellValue () Metodo:

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

E quando il tipo di cella è FORMULA , possiamo usare il metodo getCellFormula () :

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

3.2. Scrivere in Excel

Apache POI utilizza le stesse interfacce presentate nella sezione precedente per la scrittura su un file Excel e ha un supporto migliore per lo stile rispetto a JExcel.

Creiamo un metodo che scriva un elenco di persone su un foglio intitolato "Persone" . Innanzitutto, creeremo e definiremo una riga di intestazione che contiene le celle "Nome" ed "Età" :

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

Successivamente, scriviamo il contenuto della tabella con uno stile diverso:

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

Infine, scriviamo il contenuto in un file 'temp.xlsx' nella directory corrente e chiudiamo la cartella di lavoro:

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();

Testiamo i metodi sopra in un test JUnit che scrive il contenuto nel file temp.xlsx , quindi legge lo stesso file per verificare che contenga il testo che abbiamo scritto:

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

La libreria JExcel è una libreria leggera che ha il vantaggio di essere più facile da usare rispetto a Apache POI, ma con lo svantaggio che fornisce solo il supporto per l'elaborazione di file Excel nel formato .xls (1997-2003).

Al momento, i file .xlsx non sono supportati.

4.1. Leggere da Excel

Per lavorare con i file Excel, questa libreria fornisce una serie di classi che rappresentano le diverse parti di un file Excel. La classe Workbook rappresenta l'intera raccolta di fogli. La classe Sheet rappresenta un singolo foglio e la classe Cell rappresenta una singola cella di un foglio di calcolo.

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. Conclusione

Questo tutorial ha illustrato come utilizzare l' API POI di Apache e l' API JExcel per leggere e scrivere un file Excel da un programma Java.

Il codice sorgente completo per questo articolo può essere trovato nel progetto GitHub.