Java excel чтение данных

Рассказывает автор блога javarevisited.blogspot.ru


Из этой статьи вы сможете узнать о записи и чтении данных из Excel файлов в Java (будет рассмотрен как XLS, так и XLSX формат). Мы будем использовать библиотеку Apache POI и сосредоточимся на работе с типами String и Date, работа с последним происходит достаточно хитро. Напомню, что работу с числами мы уже рассмотрели в другой статье.

Библиотеку poi-XX.jar вы можете использовать для всех старых (xls, doc, ppt) файлов Microsoft Office, для новых (xlsx, docx, pptx) вам понадобится poi-ooxml-XX.jar. Очень важно понимать, что к чему относится, т.к. используемые классы тоже разные — для старых расширений это HSSFWorkbook, а для новых — XSSFWorkbook.

Подготовка: загрузка библиотек и зависимостей

Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.

Во втором случае вам нужно просто добавить следующие две зависимости:

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.12</version>
    </dependency>
  </dependencies>

Самое удобное в Maven — что он загрузит не только указанные poi.jar и poi-ooxml.jar, но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar, stax-api-1.0.1.jar, poi-ooxml-schemas-3.12.jar и commons-codec-1.9.jar.

Если вы будете добавлять библиотеки вручную — не забудьте о вышеназванных файлах. Скачать всё можно отсюда. Помните — если вы загрузите только poi-XX.jar, то ваш код скомпилируется без ошибок, но потом упадёт с java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject, так как внутри будет вызываться xmlbeans.jar.

Запись

В этом примере мы запишем в xls файл следующие данные: в первую ячейку — строку с именем, а во вторую — дату рождения. Вот пошаговая инструкция:

  • Создаём объект HSSFWorkBook;
  • Создаём лист, используя на объекте, созданном в предыдущем шаге, createSheet();
  • Создаём на листе строку, используя createRow();
  • Создаём в строке ячейку — createCell();
  • Задаём значение ячейки через setCellValue();
  • Записываем workbook в File через FileOutputStream;
  • Закрываем workbook, вызывая close().

Для записи строк или чисел этого вполне достаточно, но чтобы записать дату, нам понадобится сделать ещё кое-что:

  • Создать DateFormat;
  • Создать CellStyle;
  • Записать DateFormat в CellStyle;
  • Записать CellStyle в ячейку;
  • Теперь в эту ячейку можно записать объект Date через всё тот же setCellValue;
  • Чтобы дата поместилась в ячейку, нам нужно добавить столбцу свойство автоматически менять размер: sheet.autoSizeColumn(1).

Всё вместе это будет выглядеть так:

@SuppressWarnings("deprecation")
    public static void writeIntoExcel(String file) throws FileNotFoundException, IOException{
        Workbook book = new HSSFWorkbook();
        Sheet sheet = book.createSheet("Birthdays");

        // Нумерация начинается с нуля
        Row row = sheet.createRow(0); 
        
        // Мы запишем имя и дату в два столбца
        // имя будет String, а дата рождения --- Date,
        // формата dd.mm.yyyy
        Cell name = row.createCell(0);
        name.setCellValue("John");
        
        Cell birthdate = row.createCell(1);
        
        DataFormat format = book.createDataFormat();
        CellStyle dateStyle = book.createCellStyle();
        dateStyle.setDataFormat(format.getFormat("dd.mm.yyyy"));
        birthdate.setCellStyle(dateStyle);
        
 
        // Нумерация лет начинается с 1900-го
        birthdate.setCellValue(new Date(110, 10, 10));
        
        // Меняем размер столбца
        sheet.autoSizeColumn(1);
        
        // Записываем всё в файл
        book.write(new FileOutputStream(file));
        book.close();
    }

Чтение

Теперь мы считаем из только что созданного файла то, что мы туда записали.

  • Для начала создадим HSSFWorkBook, передав в конструктор FileInputStream;
  • Получаем лист, передавая в getSheet() его номер или название;
  • Получаем строку, используя getRow();
  • Получаем ячейку, используя getCell();
  • Узнаём тип ячейки, используя на ней getCellType();
  • В зависимости от типа ячейки, читаем её значения, используя getStringCellValue(), getNumericCellValue() или getDateCellValue();
  • Закрываем workbook используя close().

Напомню, что дату Excel хранит как числа, т.е. тип ячейки всё равно будет CELL_TYPE_NUMERIC.

В виде кода это будет выглядеть следующим образом:

public static void readFromExcel(String file) throws IOException{
        HSSFWorkbook myExcelBook = new HSSFWorkbook(new FileInputStream(file));
        HSSFSheet myExcelSheet = myExcelBook.getSheet("Birthdays");
        HSSFRow row = myExcelSheet.getRow(0);
        
        if(row.getCell(0).getCellType() == HSSFCell.CELL_TYPE_STRING){
            String name = row.getCell(0).getStringCellValue();
            System.out.println("name : " + name);
        }
        
        if(row.getCell(1).getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
            Date birthdate = row.getCell(1).getDateCellValue();
            System.out.println("birthdate :" + birthdate);
        }
        
        myExcelBook.close();
        
    }

В заключение

Как уже упомналось выше, чтение из xlsx файлов ничем принципиально не отличается — нужно только вместо HSSFWorkBook, HSSFSheet, HSSFRow (и прочих) из poi-XX.jar использовать XSSFWorkBook, XSSFSheet, XSSFRow из poi-ooxml-XX.jar. Это всё, что вам нужно знать для чтения и записи в файлы Excel. Разумеется, с помощью библиотеки Apache POI вы можете сделать гораздо больше, но эта статья должна помочь вам быстрее в ней освоиться.

Перевод статьи «How to Read Write Excel file in Java — POI Example»

Интеграция электронных таблиц MS Excel и Java.

Описание:

В современном мире очень много случаев, при которых необходимо интегрировать MS
Excel с Java. Например, при разработке Enterprise-приложения в некой финансовой
сфере, вам необходимо предоставить счет для заинтересованных лиц, а проще всего
выставлять счет на MS Excel.

Обзор существующих API MS Excel для Java:

Рассмотрим основные API:

  • Docx4j — это API с открытым исходным кодом, для создания и манипулирования документами формата Microsoft Open XML, к которым отросятся Word docx, Powerpoint pptx, Excel xlsx файлы. Он очень похож на Microsoft OpenXML SDK, но реализован на языке Java. Docx4j использует JAXB архитектуру для создания представления объекта в памяти. Docx4j акцентирует свое внимание на всесторонней поддержке заявленного формата, но от пользователя данного API требуется знание и понимание технологии JAXB и структуры Open XML.

  • Apache POI — это набор API с открытым исходным кодом, который предлагает определенные функции для чтения и записи различных документов, базирующихся на Office Open XML стандартах (OOXML) и Microsoft OLE2 форматe документов (OLE2). OLE2 файлы включают большинство Microsoft Office форматов, таких как doc, xls, ppt. Office Open XML формат это новый стандарт базирующийся на XML разметке, и используется в файлах Microsoft office 2007 и старше.

  • Aspose for Java — набор платных Java APIs, которые помогают разработчикам в работе с популярными форматами бизнес файлов, такими как документы Microsoft Word, таблицы Microsoft Excel, презентации Microsoft PowerPoint, PDF файлы Adobe Acrobat, emails, изображения, штрих-коды и оптические распознавания символов.

Каждое API проектируется для того, чтобы выполнять широкий спектр создания документов, различные манипуляции и преобразования быстро и легко, экономя время и позволяя разработчикам успешно программировать. Ни один API с открытым исходным кодом не имеет одной и той же комплексной поддержки функций.

Все Aspose’s APIs используют простую объектную модель документа, а одно API предназначено для работы с набором связанных форматов. Aspose’s Microsoft Office APIs, Aspose.Cells, Aspose.Words, Aspose.Slides, Aspose.Email, и Aspose.Tasks легки в работе, эффективны, надежны и независимы от других библиотек.

Преимуществом APIs с открытым исходным кодом является то, что они бесплатны и каждый может настроить их под свои задачи и цели. Это очень удобно, если у пользователя есть достаточно времени и ресурсов. Однако данные APIs не всегда имеют поддержку или документацию, и поддерживают небольшое количество функций и вариантов. Этот недостаток стоит разработчикам времени, и сокращает надежность их приложений. К преимуществам проприетарных (коммерческих) API можно отнести комплексную поддержку функционала с подробной документацией, регулярное обновление, гарантию отсутствия ошибок и обратную связь с разработчиками APIs.

В данной программе будем использовать Apache POI

Ссылки на полезные ресурсы

  • https://habr.com/post/56817/
  • https://poi.apache.org/apidocs/index.html — официальная документация
  • http://java-online.ru/java-excel.xhtml

Задание:

В данной работе вы должны реализовать следующее:

  1. Чтение с ячейки MS Excel в Java

  2. Запись с Java в MS Excel

Инструкция

  • Для обращения к MS Excel версии до 2003 включительно года с Java используется класс HSSFWorkbook
  • Для обращения к MS Excel версии 2007 и позднее с Java используется класс XSSFWorkbook
  • При операциях Обновление или Запись необходимо, чтобы MS Excel был закрыт.
Чтение ячейки с MS Excel

Чтобы считать данные с xlsx необходимо исполнить следующие шаги:

    //filePath - это путь до MS Excel
    Workbook book = new XSSFWorkbook(new FileInputStream(filePath);
    //считывается лист по индексу sheet_index. sheet_index начинается с 0
    Sheet sheet = book.getSheetAt(sheet_index);
    //считывается row по индексу row_index. row_index начинается с 0
    Row row = sheet.getRow(row_index);
    //считывается cell по индексу cell_index. cell_index начинается с 0
    Cell cell = sheet.getCell(cell_index);
Запись в ячейку MS Excel
    Workbook book = new XSSFWorkbook();
    //name - имя листа
    Sheet sheet = book.createSheet(name);
    Row row = sheet.createRow(i);
    Cell cell = row.createCell(j);
    FileInputStream fileOut = new FileInputStream(filePath);
    book.write(fileOut);
    fileOut.close();
Обновление ячейки в существующем листе MS Excel
    Workbook workbook = new XSSFWorkbook(new FileInputStream(filePath));
    Sheet sheet = workbook.getSheetAt(i);
    Row row = sheet.getRow(j);
    Cell cell = row.getCell(k);
    cell.setCellValue(value);

Подготовка: загрузка библиотек и зависимостей

Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.

Во втором случае вам нужно просто добавить следующие две зависимости:

	<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.12</version>
    </dependency>
  </dependencies>

Самое удобное в Maven — что он загрузит не только указанные poi.jar и poi-ooxml.jar, но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar,
stax-api-1.0.1.jar, poi-ooxml-schemas-3.12.jar и commons-codec-1.9.jar

Выполнение:

  1. Создать проект на java с помощью maven.

  2. Следовать инструкции «Подготовка:…» описанная выше.

  3. Создать Excel файл в корневой папке проекта.

  4. Записать в A1 и A2 любые целые числа.

  5. В папке src/main/java создать класс IOCell

    1. Создать поле
    1. Создать конструктор
    IOCell(String filePath) { this.filePath = new File(filePath)}
    1. Создать метод для чтения c Excel в Java
    public Cell getCell(int sheet, int row, int column) {
        Workbook workbook = null;
        try (FileInputStream file = new FileInputStream(filePath)) {
            workbook = new XSSFWorkbook(file);
        } catch (FileNotFoundException e) {
            System.out.println("file is not exists");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return workbook.getSheetAt(sheet).getRow(row).getCell(column);
    }
    1. Создать метод для записи с Java в Excel
        public void setCell(int row, int column, double val) {
        Workbook workbook = null;
         try (FileInputStream file = new FileInputStream(filePath)) {
             workbook = new XSSFWorkbook(file);
             Sheet sheet = workbook.getSheetAt(0);
             sheet.getRow(row).getCell(column).setCellValue(val);
         } catch (IOException e) {
             e.printStackTrace();
         }
        try (OutputStream fileOut = new FileOutputStream(filePath)) {
            workbook.write(fileOut);
        } catch (FileNotFoundException e) {
            System.out.println("file is not exist AAAA");
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    }
    
  6. В папке src/main/java создать класс Main

    1. Создать поле
        private static final String filePath = "NAME_OF_EXCEL_FILE";
    1. Создать метод
    public static void main(String[] args) {
        IOCell ioCell = new IOCell(filePath);
    
        Cell x = ioCell.getCell(0, 1, 0);
        Cell y = ioCell.getCell(0,  1, 1);
        System.out.println("first number: " + x.toString());
        System.out.println("second number: " + y.toString());
        //Write x * y
        ioCell.setCell(4, 0, x.getNumericCellValue() * y.getNumericCellValue());
        //Write x + y
        ioCell.setCell(4, 1, x.getNumericCellValue() + y.getNumericCellValue());
        System.out.println("Interactions is complete successfully");
    }
  7. Запускаем приложение и смотрим в консоль.

I want to read and write an Excel file from Java with 3 columns and N rows, printing one string in each cell. Can anyone give me simple code snippet for this? Do I need to use any external lib or does Java have built-in support for it?

I want to do the following:

for(i=0; i <rows; i++)
     //read [i,col1] ,[i,col2], [i,col3]

for(i=0; i<rows; i++)
    //write [i,col1], [i,col2], [i,col3]

Paolo Forgia's user avatar

Paolo Forgia

6,5328 gold badges46 silver badges58 bronze badges

asked Oct 4, 2009 at 10:54

user177785's user avatar

1

Try the Apache POI HSSF. Here’s an example on how to read an excel file:

try {
    POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file));
    HSSFWorkbook wb = new HSSFWorkbook(fs);
    HSSFSheet sheet = wb.getSheetAt(0);
    HSSFRow row;
    HSSFCell cell;

    int rows; // No of rows
    rows = sheet.getPhysicalNumberOfRows();

    int cols = 0; // No of columns
    int tmp = 0;

    // This trick ensures that we get the data properly even if it doesn't start from first few rows
    for(int i = 0; i < 10 || i < rows; i++) {
        row = sheet.getRow(i);
        if(row != null) {
            tmp = sheet.getRow(i).getPhysicalNumberOfCells();
            if(tmp > cols) cols = tmp;
        }
    }

    for(int r = 0; r < rows; r++) {
        row = sheet.getRow(r);
        if(row != null) {
            for(int c = 0; c < cols; c++) {
                cell = row.getCell((short)c);
                if(cell != null) {
                    // Your code here
                }
            }
        }
    }
} catch(Exception ioe) {
    ioe.printStackTrace();
}

On the documentation page you also have examples of how to write to excel files.

Greatmar2's user avatar

answered Oct 4, 2009 at 10:59

rogeriopvl's user avatar

rogeriopvlrogeriopvl

50.8k8 gold badges54 silver badges58 bronze badges

7

Apache POI can do this for you. Specifically the HSSF module. The quick guide is most useful. Here’s how to do what you want — specifically create a sheet and write it out.

Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow((short)0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);

// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(
createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Morteza Jalambadani's user avatar

answered Oct 4, 2009 at 10:57

Brian Agnew's user avatar

Brian AgnewBrian Agnew

267k36 gold badges333 silver badges441 bronze badges

2

First add all these jar files in your project class path:

  1. poi-scratchpad-3.7-20101029
  2. poi-3.2-FINAL-20081019
  3. poi-3.7-20101029
  4. poi-examples-3.7-20101029
  5. poi-ooxml-3.7-20101029
  6. poi-ooxml-schemas-3.7-20101029
  7. xmlbeans-2.3.0
  8. dom4j-1.6.1

Code for writing in a excel file:

public static void main(String[] args) {
    //Blank workbook
    XSSFWorkbook workbook = new XSSFWorkbook();

    //Create a blank sheet
    XSSFSheet sheet = workbook.createSheet("Employee Data");

    //This data needs to be written (Object[])
    Map<String, Object[]> data = new TreeMap<String, Object[]>();
    data.put("1", new Object[]{"ID", "NAME", "LASTNAME"});
    data.put("2", new Object[]{1, "Amit", "Shukla"});
    data.put("3", new Object[]{2, "Lokesh", "Gupta"});
    data.put("4", new Object[]{3, "John", "Adwards"});
    data.put("5", new Object[]{4, "Brian", "Schultz"});

    //Iterate over data and write to sheet
    Set<String> keyset = data.keySet();

    int rownum = 0;
    for (String key : keyset) 
    {
        //create a row of excelsheet
        Row row = sheet.createRow(rownum++);

        //get object array of prerticuler key
        Object[] objArr = data.get(key);

        int cellnum = 0;

        for (Object obj : objArr) 
        {
            Cell cell = row.createCell(cellnum++);
            if (obj instanceof String) 
            {
                cell.setCellValue((String) obj);
            }
            else if (obj instanceof Integer) 
            {
                cell.setCellValue((Integer) obj);
            }
        }
    }
    try 
    {
        //Write the workbook in file system
        FileOutputStream out = new FileOutputStream(new File("C:\Documents and Settings\admin\Desktop\imp data\howtodoinjava_demo.xlsx"));
        workbook.write(out);
        out.close();
        System.out.println("howtodoinjava_demo.xlsx written successfully on disk.");
    } 
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

Code for reading from excel file

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

public static void main(String[] args) {
    try {
        FileInputStream file = new FileInputStream(new File("C:\Documents and Settings\admin\Desktop\imp data\howtodoinjava_demo.xlsx"));

        //Create Workbook instance holding reference to .xlsx file
        XSSFWorkbook workbook = new XSSFWorkbook(file);

        //Get first/desired sheet from the workbook
        XSSFSheet sheet = workbook.getSheetAt(0);

        //Iterate through each rows one by one
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext())
        {
            Row row = rowIterator.next();
            //For each row, iterate through all the columns
            Iterator<Cell> cellIterator = row.cellIterator();

            while (cellIterator.hasNext()) 
            {
                Cell cell = cellIterator.next();
                //Check the cell type and format accordingly
                switch (cell.getCellType()) 
                {
                    case Cell.CELL_TYPE_NUMERIC:
                        System.out.print(cell.getNumericCellValue() + "t");
                        break;
                    case Cell.CELL_TYPE_STRING:
                        System.out.print(cell.getStringCellValue() + "t");
                        break;
                }
            }
            System.out.println("");
        }
        file.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Prasad Jadhav's user avatar

answered Aug 2, 2013 at 9:15

Prashant Tiwari's user avatar

0

You can also consider JExcelApi. I find it better designed than POI. There’s a tutorial here.

answered Oct 4, 2009 at 13:06

javashlook's user avatar

javashlookjavashlook

10.3k1 gold badge26 silver badges33 bronze badges

3

There is a new easy and very cool tool (10x to Kfir): xcelite

Write:

public class User { 

  @Column (name="Firstname")
  private String firstName;

  @Column (name="Lastname")
  private String lastName;

  @Column
  private long id; 

  @Column
  private Date birthDate; 
}

Xcelite xcelite = new Xcelite();    
XceliteSheet sheet = xcelite.createSheet("users");
SheetWriter<User> writer = sheet.getBeanWriter(User.class);
List<User> users = new ArrayList<User>();
// ...fill up users
writer.write(users); 
xcelite.write(new File("users_doc.xlsx"));

Read:

Xcelite xcelite = new Xcelite(new File("users_doc.xlsx"));
XceliteSheet sheet = xcelite.getSheet("users");
SheetReader<User> reader = sheet.getBeanReader(User.class);
Collection<User> users = reader.read();

Johannes Jander's user avatar

answered Dec 23, 2014 at 8:21

Ran Adler's user avatar

Ran AdlerRan Adler

3,52128 silver badges27 bronze badges

0

For reading a xlsx file we can use Apache POI libs
Try this:

public static void readXLSXFile() throws IOException
    {
        InputStream ExcelFileToRead = new FileInputStream("C:/Test.xlsx");
        XSSFWorkbook  wb = new XSSFWorkbook(ExcelFileToRead);

        XSSFWorkbook test = new XSSFWorkbook(); 

        XSSFSheet sheet = wb.getSheetAt(0);
        XSSFRow row; 
        XSSFCell cell;

        Iterator rows = sheet.rowIterator();

        while (rows.hasNext())
        {
            row=(XSSFRow) rows.next();
            Iterator cells = row.cellIterator();
            while (cells.hasNext())
            {
                cell=(XSSFCell) cells.next();

                if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING)
                {
                    System.out.print(cell.getStringCellValue()+" ");
                }
                else if(cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC)
                {
                    System.out.print(cell.getNumericCellValue()+" ");
                }
                else
                {
                    //U Can Handel Boolean, Formula, Errors
                }
            }
            System.out.println();
        }

    }

DarkMental's user avatar

answered Apr 13, 2017 at 8:16

KIBOU Hassan's user avatar

.csv or POI will certainly do it, but you should be aware of Andy Khan’s JExcel. I think it’s by far the best Java library for working with Excel there is.

answered Oct 4, 2009 at 12:50

duffymo's user avatar

duffymoduffymo

304k44 gold badges368 silver badges558 bronze badges

2

A simple CSV file should suffice

answered Oct 4, 2009 at 11:01

John La Rooy's user avatar

John La RooyJohn La Rooy

292k52 gold badges363 silver badges501 bronze badges

8

String path="C:\Book2.xlsx";
try {

        File f = new File( path );
        Workbook wb = WorkbookFactory.create(f);
        Sheet mySheet = wb.getSheetAt(0);
        Iterator<Row> rowIter = mySheet.rowIterator();
        for ( Iterator<Row> rowIterator = mySheet.rowIterator() ;rowIterator.hasNext(); )
        {
            for (  Iterator<Cell> cellIterator = ((Row)rowIterator.next()).cellIterator() ; cellIterator.hasNext() ;  ) 
            {
                System.out.println ( ( (Cell)cellIterator.next() ).toString() );
            }
            System.out.println( " **************************************************************** ");
        }
    } catch ( Exception e )
    {
        System.out.println( "exception" );
        e.printStackTrace();
    }

and make sure to have added the jars poi and poi-ooxml (org.apache.poi) to your project

instinct's user avatar

instinct

4301 gold badge7 silver badges24 bronze badges

answered Apr 11, 2014 at 10:24

Toumi's user avatar

ToumiToumi

2,8673 gold badges37 silver badges30 bronze badges

For reading data from .xlsx workbooks we need to use XSSFworkbook classes.

XSSFWorkbook xlsxBook = new XSSFWorkbook(fis);

XSSFSheet sheet = xlsxBook.getSheetAt(0); etc.

We need to use Apache-poi 3.9 @ http://poi.apache.org/

For detailed info with example visit
: http://java-recent.blogspot.in

CuberChase's user avatar

CuberChase

4,4305 gold badges33 silver badges52 bronze badges

answered Jun 18, 2013 at 1:47

Satish Reddy's user avatar

1

Sure , you will find the code below useful and easy to read and write. This is a util class which you can use in your main method and then you are good to use all methods below.

     public class ExcelUtils {
     private static XSSFSheet ExcelWSheet;
     private static XSSFWorkbook ExcelWBook;
     private static XSSFCell Cell;
     private static XSSFRow Row;
     File fileName = new File("C:\Users\satekuma\Pro\Fund.xlsx");
     public void setExcelFile(File Path, String SheetName) throws Exception                

    try {
        FileInputStream ExcelFile = new FileInputStream(Path);
        ExcelWBook = new XSSFWorkbook(ExcelFile);
        ExcelWSheet = ExcelWBook.getSheet(SheetName);
    } catch (Exception e) {
        throw (e);
    }

}


      public static String getCellData(int RowNum, int ColNum) throws Exception {

    try {
        Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
        String CellData = Cell.getStringCellValue();
        return CellData;
    } catch (Exception e) {

        return "";

    }

}
public static void setCellData(String Result, int RowNum, int ColNum, File Path) throws Exception {

    try {
        Row = ExcelWSheet.createRow(RowNum - 1);
        Cell = Row.createCell(ColNum - 1);
        Cell.setCellValue(Result);
        FileOutputStream fileOut = new FileOutputStream(Path);
        ExcelWBook.write(fileOut);
        fileOut.flush();
        fileOut.close();
    } catch (Exception e) {

        throw (e);

    }

}

}

Hrach Ghapantsyan's user avatar

answered May 6, 2015 at 14:58

satender's user avatar

satendersatender

1,16913 silver badges12 bronze badges

using spring apache poi repo

if (fileName.endsWith(".xls")) {



File myFile = new File("file location" + fileName);
                FileInputStream fis = new FileInputStream(myFile);

                org.apache.poi.ss.usermodel.Workbook workbook = null;
                try {
                    workbook = WorkbookFactory.create(fis);
                } catch (InvalidFormatException e) {

                    e.printStackTrace();
                }


                org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);


                Iterator<Row> rowIterator = sheet.iterator();


                while (rowIterator.hasNext()) {
                    Row row = rowIterator.next();

                    Iterator<Cell> cellIterator = row.cellIterator();
                    while (cellIterator.hasNext()) {

                        Cell cell = cellIterator.next();
                        switch (cell.getCellType()) {
                        case Cell.CELL_TYPE_STRING:
                            System.out.print(cell.getStringCellValue());
                            break;
                        case Cell.CELL_TYPE_BOOLEAN:
                            System.out.print(cell.getBooleanCellValue());
                            break;
                        case Cell.CELL_TYPE_NUMERIC:
                            System.out.print(cell.getNumericCellValue());
                            break;
                        }
                        System.out.print(" - ");
                    }
                    System.out.println();
                }
            }

goto's user avatar

goto

7,79110 gold badges48 silver badges58 bronze badges

answered Feb 22, 2017 at 9:53

Rahul.P's user avatar

I edited the most voted one a little cuz it didn’t count blanks columns or rows well not totally, so here is my code i tested it and now can get any cell in any part of an excel file. also now u can have blanks columns between filled column and it will read them

  try {
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(Dir));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;

int rows; // No of rows
rows = sheet.getPhysicalNumberOfRows();

int cols = 0; // No of columns
int tmp = 0;
int cblacks=0;

// This trick ensures that we get the data properly even if it doesn't start from first few rows
for(int i = 0; i <= 10 || i <= rows; i++) {
    row = sheet.getRow(i);
    if(row != null) {
        tmp = sheet.getRow(i).getPhysicalNumberOfCells();
        if(tmp >= cols) cols = tmp;else{rows++;cblacks++;}
    }

    cols++;
}
cols=cols+cblacks;
for(int r = 0; r < rows; r++) {
    row = sheet.getRow(r);
    if(row != null) {
        for(int c = 0; c < cols; c++) {
            cell = row.getCell(c);
            if(cell != null) {
                System.out.print(cell+"n");//Your Code here
            }
        }
    }
}} catch(Exception ioe) {
ioe.printStackTrace();}

answered Oct 4, 2015 at 20:16

Nahuel Illescas's user avatar

If column number are varing you can use this

package com.org.tests;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
import java.io.IOException;

public class ExcelSimpleTest 
{   
    String path;
    public FileInputStream fis = null;
    private XSSFWorkbook workbook = null;
    private XSSFSheet sheet = null;
    private XSSFRow row   =null;
    private XSSFCell cell = null;

    public ExcelSimpleTest() throws IOException
    {
        path = System.getProperty("user.dir")+"\resources\Book1.xlsx";
        fis = new FileInputStream(path); 
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheetAt(0);
    }
    public void ExelWorks()
    {
        int index = workbook.getSheetIndex("Sheet1");
        sheet = workbook.getSheetAt(index);
        int rownumber=sheet.getLastRowNum()+1;  

        for (int i=1; i<rownumber; i++ )
        {
            row = sheet.getRow(i);
            int colnumber = row.getLastCellNum();
            for (int j=0; j<colnumber; j++ )
            {
                cell = row.getCell(j);
                System.out.println(cell.getStringCellValue());
            }
        }
    }   
    public static void main(String[] args) throws IOException 
    {
        ExcelSimpleTest excelwork = new ExcelSimpleTest();
        excelwork.ExelWorks();
    }
}

The corresponding mavendependency can be found here

Ohmen's user avatar

Ohmen

6,1343 gold badges26 silver badges35 bronze badges

answered Aug 26, 2016 at 6:06

Senthil Kumar Natarajan's user avatar

1

Another way to read/write Excel files is to use Windmill. It provides a fluent API to process Excel and CSV files.

Import data

try (Stream<Row> rowStream = Windmill.parse(FileSource.of(new FileInputStream("myFile.xlsx")))) {
  rowStream
    // skip the header row that contains the column names
    .skip(1)
    .forEach(row -> {
      System.out.println(
        "row n°" + row.rowIndex()
        + " column 'User login' value : " + row.cell("User login").asString()
        + " column n°3 number value : " + row.cell(2).asDouble().value() // index is zero-based
      );
    });
}

Export data

Windmill
  .export(Arrays.asList(bean1, bean2, bean3))
  .withHeaderMapping(
    new ExportHeaderMapping<Bean>()
      .add("Name", Bean::getName)
      .add("User login", bean -> bean.getUser().getLogin())
  )
  .asExcel()
  .writeTo(new FileOutputStream("Export.xlsx"));

answered Sep 30, 2017 at 15:07

amanteaux's user avatar

amanteauxamanteaux

1,94319 silver badges23 bronze badges

You need Apache POI library and this code below should help you

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Iterator;
    //*************************************************************
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;

    //*************************************************************
   public class AdvUse {

    private static Workbook wb ; 
    private static Sheet sh ; 
    private static FileInputStream fis ; 
    private static FileOutputStream fos  ; 
    private static Row row  ; 
    private static Cell cell  ;
    private static String ExcelPath ; 

    //*************************************************************
    public static void setEcxelFile(String ExcelPath, String SheetName) throws Exception {
    try {
   File f= new File(ExcelPath); 
   if(!f.exists()){
       f.createNewFile();
       System.out.println("File not Found so created");
   }

    fis = new FileInputStream("./testData.xlsx");
    wb = WorkbookFactory.create(fis); 
    sh = wb.getSheet("SheetName");
    if(sh == null){
        sh = wb.getSheet(SheetName); 
    }
    }catch(Exception e)
    {System.out.println(e.getMessage());
    }
    }

      //*************************************************************
      public static void setCellData(String text , int rowno , int colno){
    try{
        row = sh.getRow(rowno);
        if(row == null){
            row = sh.createRow(rowno);
        }
        cell = row.getCell(colno);
        if(cell!=null){
            cell.setCellValue(text);

        }
        else{
            cell = row.createCell(colno);
            cell.setCellValue(text);

        }
        fos = new FileOutputStream(ExcelPath);
        wb.write(fos);
        fos.flush();
        fos.close();
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
    }

      //*************************************************************
      public static String getCellData(int rowno , int colno){
        try{

            cell = sh.getRow(rowno).getCell(colno); 
            String CellData = null ;
            switch(cell.getCellType()){
            case  STRING :
                CellData = cell.getStringCellValue();
               break ; 
            case NUMERIC : 
                CellData = Double.toString(cell.getNumericCellValue());
                if(CellData.contains(".o")){
                    CellData = CellData.substring(0,CellData.length()-2);

                }
            break ; 
            case BLANK : 
            CellData = ""; break ; 

            }
            return CellData;
        }catch(Exception e){return ""; }
    }

       //*************************************************************
      public static int getLastRow(){
        return sh.getLastRowNum();
    }

answered Mar 30, 2019 at 16:48

Abdo Bmz's user avatar

Abdo BmzAbdo Bmz

6221 gold badge10 silver badges24 bronze badges

You can not read & write same file in parallel(Read-write lock). But, we can do parallel operations on temporary data(i.e. Input/output stream). Write the data to file only after closing the input stream. Below steps should be followed.

  • Open the file to Input stream
  • Open the same file to an Output Stream
  • Read and do the processing
  • Write contents to output stream.
  • Close the read/input stream, close file
  • Close output stream, close file.

Apache POI — read/write same excel example

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class XLSXReaderWriter {

    public static void main(String[] args) {

        try {
            File excel = new File("D://raju.xlsx");
            FileInputStream fis = new FileInputStream(excel);
            XSSFWorkbook book = new XSSFWorkbook(fis);
            XSSFSheet sheet = book.getSheetAt(0);

            Iterator<Row> itr = sheet.iterator();

            // Iterating over Excel file in Java
            while (itr.hasNext()) {
                Row row = itr.next();

                // Iterating over each column of Excel file
                Iterator<Cell> cellIterator = row.cellIterator();
                while (cellIterator.hasNext()) {

                    Cell cell = cellIterator.next();

                    switch (cell.getCellType()) {
                    case Cell.CELL_TYPE_STRING:
                        System.out.print(cell.getStringCellValue() + "t");
                        break;
                    case Cell.CELL_TYPE_NUMERIC:
                        System.out.print(cell.getNumericCellValue() + "t");
                        break;
                    case Cell.CELL_TYPE_BOOLEAN:
                        System.out.print(cell.getBooleanCellValue() + "t");
                        break;
                    default:

                    }
                }
                System.out.println("");
            }

            // writing data into XLSX file
            Map<String, Object[]> newData = new HashMap<String, Object[]>();
            newData.put("1", new Object[] { 1d, "Raju", "75K", "dev",
                    "SGD" });
            newData.put("2", new Object[] { 2d, "Ramesh", "58K", "test",
                    "USD" });
            newData.put("3", new Object[] { 3d, "Ravi", "90K", "PMO",
                    "INR" });

            Set<String> newRows = newData.keySet();
            int rownum = sheet.getLastRowNum();

            for (String key : newRows) {
                Row row = sheet.createRow(rownum++);
                Object[] objArr = newData.get(key);
                int cellnum = 0;
                for (Object obj : objArr) {
                    Cell cell = row.createCell(cellnum++);
                    if (obj instanceof String) {
                        cell.setCellValue((String) obj);
                    } else if (obj instanceof Boolean) {
                        cell.setCellValue((Boolean) obj);
                    } else if (obj instanceof Date) {
                        cell.setCellValue((Date) obj);
                    } else if (obj instanceof Double) {
                        cell.setCellValue((Double) obj);
                    }
                }
            }

            // open an OutputStream to save written data into Excel file
            FileOutputStream os = new FileOutputStream(excel);
            book.write(os);
            System.out.println("Writing on Excel file Finished ...");

            // Close workbook, OutputStream and Excel file to prevent leak
            os.close();
            book.close();
            fis.close();

        } catch (FileNotFoundException fe) {
            fe.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }
}

Community's user avatar

answered Jul 20, 2018 at 21:46

Raju's user avatar

RajuRaju

2,8628 gold badges38 silver badges57 bronze badges

Please use Apache POI libs and try this.

    try
    {
        FileInputStream x = new FileInputStream(new File("/Users/rajesh/Documents/rajesh.xls"));

        //Create Workbook instance holding reference to .xlsx file
        Workbook workbook = new HSSFWorkbook(x);

        //Get first/desired sheet from the workbook
        Sheet sheet = workbook.getSheetAt(0);

        //Iterate through each rows one by one
        for (Iterator<Row> iterator = sheet.iterator(); iterator.hasNext();) {
            Row row = (Row) iterator.next();
            for (Iterator<Cell> iterator2 = row.iterator(); iterator2
                    .hasNext();) {
                Cell cell = (Cell) iterator2.next();
                System.out.println(cell.getStringCellValue());              
            }               
        }         
        x.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
   }
}

Majid Laissi's user avatar

Majid Laissi

19k19 gold badges65 silver badges105 bronze badges

answered Nov 28, 2014 at 11:41

Rajesh Chaudhary's user avatar

When using the apache poi 4.1.2. The celltype changes a bit. Below is an example

    try {
        File excel = new File("/home/name/Downloads/bb.xlsx");
        FileInputStream fis = new FileInputStream(excel);
        XSSFWorkbook book = new XSSFWorkbook(fis);
        XSSFSheet sheet = book.getSheetAt(0);

        Iterator<Row> itr = sheet.iterator();

        // Iterating over Excel file in Java
        while (itr.hasNext()) {
            Row row = itr.next();

            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {



                Cell cell = cellIterator.next();



                switch (cell.getCellType()) {
                case STRING:
                    System.out.print(cell.getStringCellValue() + "t");
                    break;
                case NUMERIC:
                    System.out.print(cell.getNumericCellValue() + "t");
                    break;
                case BOOLEAN:
                    System.out.print(cell.getBooleanCellValue() + "t");
                    break;
                default:


                }
            }
            System.out.println("");}
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

answered May 22, 2020 at 8:44

mumbasa's user avatar

mumbasamumbasa

5526 silver badges11 bronze badges

If you go for third party library option, try using Aspose.Cells API that enables Java Applications to create (read/write) and manage Excel spreadsheets efficiently without requiring Microsoft Excel.

e.g

Sample code:

1.

//Load sample workbook
Workbook wb = new Workbook(dirPath + "sample.xlsx");

//Access first worksheet
Worksheet ws = wb.getWorksheets().get(0);

//Access cells iterator
Iterator itrat = ws.getCells().iterator();

//Print cells name in iterator
while(itrat.hasNext())
{
    Cell cell = (Cell)itrat.next();

    System.out.println(cell.getName() + ": " + cell.getStringValue().trim());
}
Workbook book = new Workbook("sample.xlsx");
Worksheet sheet = book.getWorksheets().get(0);
Range range = sheet.getCells().getMaxDisplayRange();//You may also create your desired range (in the worksheet) using, e.g sheet.getCells().createRange("A1", "J11");
Iterator rangeIterator = range.iterator();
while(rangeIterator.hasNext())
{
Cell cell = (Cell)rangeIterator.next();
//your code goes here.
}

Hope, this helps a bit.

PS. I am working as Support developer/ Evangelist at Aspose.

answered Sep 2, 2020 at 19:29

Amjad Sahi's user avatar

Amjad SahiAmjad Sahi

1,7531 gold badge9 silver badges15 bronze badges

If you need to do anything more with office documents in Java, go for POI as mentioned.

For simple reading/writing an excel document like you requested, you can use the CSV format (also as mentioned):

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class CsvWriter {
 public static void main(String args[]) throws IOException {

  String fileName = "test.xls";

  PrintWriter out = new PrintWriter(new FileWriter(fileName));
  out.println("a,b,c,d");
  out.println("e,f,g,h");
  out.println("i,j,k,l");
  out.close();

  BufferedReader in = new BufferedReader(new FileReader(fileName));
  String line = null;
  while ((line = in.readLine()) != null) {

   Scanner scanner = new Scanner(line);
   String sep = "";
   while (scanner.hasNext()) {
    System.out.println(sep + scanner.next());
    sep = ",";
   }
  }
  in.close();
 }
}

answered Oct 4, 2009 at 12:02

Adriaan Koster's user avatar

Adriaan KosterAdriaan Koster

15.8k5 gold badges45 silver badges60 bronze badges

This will write a JTable to a tab separated file that can be easily imported into Excel. This works.

If you save an Excel worksheet as an XML document you could also build the XML file for EXCEL with code. I have done this with word so you do not have to use third-party packages.

This could code have the JTable taken out and then just write a tab separated to any text file and then import into Excel. I hope this helps.

Code:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JTable;
import javax.swing.table.TableModel;

public class excel {
    String columnNames[] = { "Column 1", "Column 2", "Column 3" };

    // Create some data
    String dataValues[][] =
    {
        { "12", "234", "67" },
        { "-123", "43", "853" },
        { "93", "89.2", "109" },
        { "279", "9033", "3092" }
    };

    JTable table;

    excel() {
        table = new JTable( dataValues, columnNames );
    }


    public void toExcel(JTable table, File file){
        try{
            TableModel model = table.getModel();
            FileWriter excel = new FileWriter(file);

            for(int i = 0; i < model.getColumnCount(); i++){
                excel.write(model.getColumnName(i) + "t");
            }

            excel.write("n");

            for(int i=0; i< model.getRowCount(); i++) {
                for(int j=0; j < model.getColumnCount(); j++) {
                    excel.write(model.getValueAt(i,j).toString()+"t");
                }
                excel.write("n");
            }

            excel.close();

        }catch(IOException e){ System.out.println(e); }
    }

    public static void main(String[] o) {
        excel cv = new excel();
        cv.toExcel(cv.table,new File("C:\Users\itpr13266\Desktop\cs.tbv"));
    }
}

answered Feb 26, 2014 at 22:58

Doug Hauf's user avatar

Doug HaufDoug Hauf

3,0158 gold badges45 silver badges69 bronze badges

1

Все знакомы с табличным процессором Excel, который входит в стандартный пакет Microsoft Office. Напрямую в Excel очень удобно и приятно работать, но мало кто знает, что в Java этот процесс не менее приятный и увлекательный.

Последнее время мне приходилось программно парсить файлы формата .xls и .xlsx. Чтобы осуществить парсинг Excel-файла, понадобилась библиотека Apache POI. С помощью этой библиотеки можно парсить не только файлы в формате .xls, но и DOC, PPT, а также форматы, которые появились в версии Microsoft Office 2007.

В этой статье мы познакомимся с чтением данных из xls или xlsx файла в Java с помощью библиотеки Apache POI. Как всегда, немного теории по основам и практика на примере чтения простого xls файла. Пример создания нового Excel файла представлен здесь.

 Подключаем библиотеку для работы с Excel в Java

Для начала нужно создать Maven-проект и в файле pom.xml прописать следующий код зависимостей

<dependency>

        <groupId>org.apache.poi</groupId>

        <artifactId>poi</artifactId>

        <version>3.11</version>

</dependency>

Чтение Excel файла на Java

Библиотека Apache POI предоставляет простой в использовании API для чтения любого xls файла. Ниже мы рассмотрим наиболее используемые классы для чтения содержимого Excel таблиц:

Код для чтения Excel документов в формате xls

В листинге ниже приведен типичный пример инициализации HSSFWorkbook и HSSFSheet для считывания данных из .xls файлов.

// получаем файл в формате xls

FileInputStream file = new FileInputStream(new File(«C:\simplexcel.xls»));

// формируем из файла экземпляр HSSFWorkbook

HSSFWorkbook workbook = new HSSFWorkbook(file);

// выбираем первый лист для обработки

// нумерация начинается с 0

HSSFSheet sheet = workbook.getSheetAt(0);

// получаем Iterator по всем строкам в листе

Iterator<Row> rowIterator = sheet.iterator();

// получаем Iterator по всем ячейкам в строке

Iterator<Cell> cellIterator = row.cellIterator();

Код для чтения Excel документов в формате .xlsx

Ниже приведен фрагмент кода для инициализации работы с Excel файлами в формате .xlsx:

// получаем файл в формате xlsx

FileInputStream file = new FileInputStream(new File(«C:\simplexcelx.xlsx»));

// получаем экземпляр XSSFWorkbook для обработки xlsx файла

XSSFWorkbook workbook = new XSSFWorkbook (file);

// выбираем первый лист для обработки

// нумерация начинается из 0

XSSFSheet sheet = workbook.getSheetAt(0);

// получаем Iterator по всем строкам в листе

Iterator<Row> rowIterator = sheet.iterator();

// получаем Iterator по всем ячейкам в строке

Iterator<Cell> cellIterator = row.cellIterator();

Практика. Создаем простой Excel для работы

1

Пишем парсер на Java

Назовем класс ExcelParser.java с методом parse, который принимает текстовый параметр fileName

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

package ua.com.prologistic.excel;

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 java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Iterator;

public class ExcelParser {

    public static String parse(String fileName) {

    //инициализируем потоки

        String result = «»;

        InputStream inputStream = null;

        HSSFWorkbook workBook = null;

        try {

            inputStream = new FileInputStream(fileName);

            workBook = new HSSFWorkbook(inputStream);

        } catch (IOException e) {

            e.printStackTrace();

        }

     //разбираем первый лист входного файла на объектную модель

        Sheet sheet = workBook.getSheetAt(0);

        Iterator<Row> it = sheet.iterator();

     //проходим по всему листу

        while (it.hasNext()) {

            Row row = it.next();

            Iterator<Cell> cells = row.iterator();

            while (cells.hasNext()) {

                Cell cell = cells.next();

                int cellType = cell.getCellType();

      //перебираем возможные типы ячеек

                switch (cellType) {

                    case Cell.CELL_TYPE_STRING:

                        result += cell.getStringCellValue() + «=»;

                        break;

                    case Cell.CELL_TYPE_NUMERIC:

                        result += «[« + cell.getNumericCellValue() + «]»;

                        break;

                    case Cell.CELL_TYPE_FORMULA:

                        result += «[« + cell.getNumericCellValue() + «]»;

                        break;

                    default:

                        result += «|»;

                        break;

                }

            }

            result += «n»;

        }

        return result;

    }

}

Создаем главный класс-ранер, где и запустим парсер:

package ua.com.prologistic;

import ua.com.prologistic.excel.ExcelParser;

public class MainClass {

    public static void main(String[] args){

        System.out.println(Parser.parse(«excel.xls»));

    }

}

Результат выполнения парсера Excel

Бонька=[4.0]

Баюн=[2.0]

Полкан=[6.0]

Барон=[3.0]

Общий вес=[15.0]

Работа с запароленным Excel файлом

В Apache POI с каждой новой версией добавляются новые возможности по работе с закрытыми/запароленными файлами. Например, мы может работать с защищенными файлами XLS (используя org.apache.poi.hssf.record.crypt) и защищенными файлами XLSX (с помощью org.apache.poi.poifs.crypt).

Если вы используете HSSF (для файла XLS), то проверить является ли он запаролленым нам поможет метод isWriteProtected(). А для работы с ним необходимо указать пароль перед самым открытием файла:

...

org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword(«здесь пароль»);

После этого можем работать с файлом.

Для XSSF нам понадобится что-то вроде такого:

POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(«protected.xlsx»));

EncryptionInfo info = new EncryptionInfo(fs);

Decryptor d = new Decryptor(info);

d.verifyPassword(Decryptor.DEFAULT_PASSWORD);

XSSFWorkbook wb = new XSSFWorkbook(d.getDataStream(fs));

При работе с более новыми версиями Apache POI, можно просто указать пароль при создании Workbook:

Workbook wb = WorkbookFactory.create(new File(«protected.xls»), «здесь пароль»));

Этот код будет работать как для HSSF, так и для XSSF.

Также смотрите примеры чтения Word документа и создания нового документа Word с помощью Apache POI.

Подписывайтесь на обновления!

Афоризм

А в письмах Вы казались мне стройнее.

Наталья Резник

Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие

 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698

На странице описания библиотеки Apache POI представлены свойства
и методы взаимодействия Java приложений с файлами Excel. Здесь рассматривается пример использования
Apache POI для чтения файлов Excel 2007 или более поздней версии. Если необходимо обрабатывать
Excel 1997-2003, то следует использовать классы, наименования которых начинаются с символа ‘H’
(см. наименование классов на странице описания Apache POI).

Открытие книги Excel

Чтобы «открыть» файл Excel как HSSFWorkbook (.xls), так и XSSFWorkbook (.xlsx) можно использовать либо
File, либо InputStream. При использовании InputStream требуется больше
памяти для загрузки файла в буффер.

Метод openBook демонстрирует использование WorkbookFactory для открытия Excel файла. Строки
использования InputStream закомментированы.

private XSSFWorkbook book;
...
private void openBook(final String path)
{
    try {
        File file = new File(path);
        book = (XSSFWorkbook) WorkbookFactory.create(file);

//      InputStream is = new FileInputStream(FILE);
//      book = (XSSFWorkbook) WorkbookFactory.create(is);
//      is.close();
    } catch (FileNotFoundException e1) {
        e.printStackTrace();
    } catch (EncryptedDocumentException e) {
        e.printStackTrace();
    } catch (InvalidFormatException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Если нужно обойти использование WorkbookFactory, т.е. использовать XSSFWorkbook (HSSFWorkbook)
напрямую, то следует использовать OPCPackage (.xlsx) или NPOIFSFileSystem (.xls).

private XSSFWorkbook book;
...
private void openBookDirectly(final String path)
{
    File file = new File(path);
    try {
        OPCPackage pkg = OPCPackage.open(file);
        book = new XSSFWorkbook(pkg);
        pkg.close();
    } catch (InvalidFormatException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Открытие страницы

При открытии страницы слеудет использовать метод getSheet с указанием в качестве параметра наименования
страницы. Здесь необходимо быть внимательным, поскольку наименования страницы по умолчанию могут быть как
«Sheet», так и «Лист», в зависимости от локализации операционной системы и Excel.

XSSFSheet sheet = book.getSheet("Лист1");

Перебор строк и ячеек

Чтобы «пройтись» по всем страницам книги и перебрать все значения в ячейках можно использовать
итераторы. Следующий код показывает использование итераторов
для перебора всех ячеек страницы.

import java.util.Iterator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
...
Iterator<Row> ri = sheet.rowIterator();

while(ri.hasNext()) {
    XSSFRow row = (XSSFRow) ri.next();

    Iterator<Cell> ci = row.cellIterator();

    while(ci.hasNext()) {
        XSSFCell cell = (XSSFCell) ci.next();
        // код
    }
}

Итераторы доступны по вызовам workbook.sheetIterator(), sheet.rowIterator() и row.cellIterator().
Но необходимо помнить, что rowIterator и cellIterator перебирают только строки и ячейки, которые созданы,
пропуская пустые строки и ячейки.

Если необходимо проверить все строки и все ячейки определенной области, то можно воспользоваться
следующим кодом.

private void readCells()
{
    // Определение граничных строк обработки
    int rowStart = Math.min(  0, sheet.getFirstRowNum());
    int rowEnd   = Math.max(100, sheet.getLastRowNum ());

    for (int rw = rowStart; rw < rowEnd; rw++) {
        XSSFRow row = sheet.getRow(rw);
        if (row == null) {
            // System.out.println(
            //      "row '" + rw + "' is not created");
            continue;
        }
        short minCol = row.getFirstCellNum();
        short maxCol = row.getLastCellNum();

        for(short col = minCol; col < maxCol; col++) {
            XSSFCell cell = row.getCell(col);
            if (cell == null) {
                // System.out.println(
                //   "cell '" + col + "' is not created");
                continue;
            }
            printCell(row, cell);
        }
    }
}

В представленном коде для чтения ячейки был использован метод getCell(int). Можно использовать
метод getCell(int, MissingCellPolicy), где
MissingCellPolicy, определяет условие возвращения пустых и
отсутствующих ячеек. Однако IDE Eclipse, где работоспособность кода проверялась, показывает, что
MissingCellPolicy упразднена (deprecated), а метод getCell(int) для ячейки типа XSSFCell
вернул правильные значения. Определение значений ячеек выполнялось в методе printCell(row, cell).

Чтение содержимого ячейки

Чтобы получить значение ячейки, необходимо знать тип её значения. Полагаю, что Вы не раз сталкивались
с числовым представлением значения даты. Если у текстовой ячейки попытаться получить числовое значение,
то будет вызвано NumberFormatException. Поэтому, необходимо первоначально определиться с типом, чтобы
использовать соответствующий метод.

Следующий код в цикле проходит по ячейкам в строке и выводит в консоль ссылочную информацию на ячейку
(например $A$3) и содержимое ячейки. Причем, сначала отображается значение, полученное методом
formatCellValue класса DataFormatter, а после символа слеша ‘/’ отображается значение,
получаемое методами getRichStringCellValue(), getDateCellValue(), getNumericCellValue(), getBooleanCellValue()
и getCellFormula() класса XSSFCell.

private void printCell(XSSFRow row, XSSFCell cell)
{
    DataFormatter formatter = new DataFormatter();
    CellReference cellRef = new CellReference(row.getRowNum(),
                                              cell.getColumnIndex());
    System.out.print(cellRef.formatAsString());
    System.out.print(" : ");

    // get the text that appears in the cell by getting 
    // the cell value and applying any data formats
    // (Date, 0.00, 1.23e9, $1.23, etc)
    String text = formatter.formatCellValue(cell);
    System.out.print(text + " / ");

    // Вывод значения в консоль
    switch (cell.getCellTypeEnum()) {
    case STRING:
        System.out.println(cell.getRichStringCellValue()
                               .getString());
        break;
    case NUMERIC:
        if (DateUtil.isCellDateFormatted(cell))
            System.out.println(cell.getDateCellValue());
        else
            System.out.println(cell.getNumericCellValue());
        break;
    case BOOLEAN:
        System.out.println(cell.getBooleanCellValue());
        break;
    case FORMULA:
        System.out.println(cell.getCellFormula());
        break;
    case BLANK:
        System.out.println();
        break;
    default:
        System.out.println();
    }
}

Пример чтения файла Excel

Работоспособность представленного на странице кода (методов), была проверена в примере,
структура которого изображена на следующем скриншоте. Это проект Eclipse, включающий
перечень необходимых библиотек для чтения файла Excel. Основной класс ExcelRead реализует
все представленные выше методы.

На следующем скриншоте представлена страница простенького файла Excel, содержащая ячейки
со значениями типа Date, String, Numeric и ячейки с формулами.

Результат чтения файла

Значения ячеек книги Excel в примере отображаются в консоли. Обратите внимание на
отличия значений до слеша и после него для типов Date и Numeric. При необходимости можно
использовать в приложении переменные соответствующего типа (Date, Integer) и должным образом
отформатировать значения.

Книга Excel открыта
Страница открыта

$A$1 : Закупки / Закупки
$B$1 : 1/20/17 / Fri Jan 20 00:00:00 MSK 2017
$A$3 : Наименование / Наименование
$B$3 : Цена / Цена
$C$3 : Количество / Количество
$D$3 : Стоимость / Стоимость
$A$4 : Сахар / Сахар
$B$4 : 50 / 50.0
$C$4 : 2 / 2.0
$D$4 : B4*C4 / B4*C4
$A$5 : Рис / Рис
$B$5 : 45 / 45.0
$C$5 : 4 / 4.0
$D$5 : B5*C5 / B5*C5
$A$7 : Итого : / Итого :
$D$7 : SUM(D4:D6) / SUM(D4:D6)
 

Скачать примеры

Исходный пример, рассмотренный в тексте страницы, можно скачать
здесь (11.7 Мб).

Для чтения данных из файла Excel можно использовать библиотеку Apache POI. Эта библиотека позволяет читать как «старый» формат Excel 97-2003 (расширение файла .xls), так и «новый» (.xlsx). В качестве примера вы можете использовать проект на github.

Добавим в наш maven-проект необходимые зависимости.

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.1</version>
</dependency>

Теперь напишем класс ExcelReader, состоящий из одного публичного метода read() и нескольких приватных.

public void read(String filename) throws IOException {
    Workbook workbook = loadWorkbook(filename);
    var sheetIterator = workbook.sheetIterator();
    while (sheetIterator.hasNext()) {
        Sheet sheet = sheetIterator.next();
        processSheet(sheet);
        System.out.println();
    }
}

В качестве параметра метод принимает полный путь до файла Excel. Затем мы вызываем метод loadWorkbook(), который возвращает интерфейс Workbook. Этот интерфейс имеет несколько реализаций в зависимости от формата файла (xls, xlsx и т.п.). В одном файле (книге) Excel имеется несколько страниц (листов). Эти листы мы обходим с помощью итератора, который возвращает метод sheetIterator(). Обработка каждого листа происходит в методе processSheet().

private Workbook loadWorkbook(String filename) throws IOException {
    var extension = filename.substring(filename.lastIndexOf(«.») + 1).toLowerCase();
    var file = new FileInputStream(new File(filename));
    switch (extension) {
        case «xls»:
            // old format
            return new HSSFWorkbook(file);
        case «xlsx»:
            // new format
            return new XSSFWorkbook(file);
        default:
            throw new RuntimeException(«Unknown Excel file extension: « + extension);
    }
}

Метод loadWorkbook() анализирует расширение файла и в зависимости от него определяет формат файла. Сначала мы создаём FileInputStream, связанный с исходным файлом, затем создаём на основе этого потока нужную реализацию интерфейса Workbook. Если расширение отличается от тех, которые мы ожидаем, то кидаем исключение.

private void processSheet(Sheet sheet) {
    System.out.println(«Sheet: « + sheet.getSheetName());
    var data = new HashMap<Integer, List<Object>>();
    var iterator = sheet.rowIterator();
    for (var rowIndex = 0; iterator.hasNext(); rowIndex++) {
        var row = iterator.next();
        processRow(data, rowIndex, row);
    }
    System.out.println(«Sheet data:»);
    System.out.println(data);
}

Метод processSheet() обрабатывает один лист из Excel. Метод getSheetName() возвращает имя листа, которое обычно в Excel пишется внизу. Далее создаём мапу data, куда будем складывать построчно данные из ячеек таблицы. Ключ такой мапы — это номер строки, а значение — все ячейки данной таблицы. Обход всех строк листа выполняем также через итератор.

private void processRow(HashMap<Integer, List<Object>> data, int rowIndex, Row row) {
    data.put(rowIndex, new ArrayList<>());
    for (var cell : row) {
        processCell(cell, data.get(rowIndex));
    }
}

Метод processRow() просто вызывает в цикле метод processCell() для каждой ячейки.

private void processCell(Cell cell, List<Object> dataRow) {
    switch (cell.getCellType()) {
        case STRING:
            dataRow.add(cell.getStringCellValue());
            break;
        case NUMERIC:
            if (DateUtil.isCellDateFormatted(cell)) {
                dataRow.add(cell.getLocalDateTimeCellValue());
            } else {
                dataRow.add(NumberToTextConverter.toText(cell.getNumericCellValue()));
            }
            break;
        case BOOLEAN:
            dataRow.add(cell.getBooleanCellValue());
            break;
        case FORMULA:
            dataRow.add(cell.getCellFormula());
            break;
        default:
            dataRow.add(» «);
    }
}

В методе processCell() для каждой ячейки мы вначале смотрим формат ячейки с помощью метода getCellType(). Всего есть 4 значимых типа для формата ячейки: это строка, число, булевый (логический) тип и формула, в которой значение ячейки вычисляется динамически на основании других ячеек.

Значение каждого типа мы получаем с помощью соответствующего метода. Для текстовых значений мы используем getStringCellValue(). Для числового типа мы сначала проверяем формат с помощью метода DateUtil.isCellDateFormatted() на предмет наличия в ней даты. Если метод возвращает true, то интерпретируем значение ячейки как дату с помощью метода getLocalDateTimeCellValue(), иначе берём значение как число с помощью getNumericCellValue(). При этом используем NumberToTextConverter, который преобразует числа в текст. Если его не использовать, то даже целые числа будут иметь один десятичный знак после запятой. Формула, возвращаемая методом getCellFormula() содержит буквенно-числовые имена ячеек и выглядит примерно так: «A2+C2*2».

Таким образом, строка за строкой, лист за листом, мы обходим весь Excel-файл и в конце выводим всё, что нам удалось из него извлечь.

Like this post? Please share to your friends:
  • Java excel to object
  • Javascript and microsoft excel
  • Java excel to json
  • Java excel cell format
  • Javascript and excel vba