0

I need to check 30 sheets in an excel file. Every sheet has a maximum of 7 rows and plenty of columns.

I need to update every row (if a certain condition is true) by adding 32 new columns after the last existing column, then save the file.

So I need to be able to do both read and write on my excel file from the same piece of code, then to save my changes updating the original excel file (using the same file name).

VinceLomba
  • 398
  • 2
  • 8
  • 18
Gaj Julije
  • 1,538
  • 15
  • 32
  • 1
    Why can't you copy file A to A and A2, then read A, and make all the required changes to A2, and then, when you are all done, replace A with A2? Or even do all of that "in place": read what needs to be read, then make all the updates you need to make? – GhostCat Jan 28 '21 at 15:43
  • I submitted an edit to your post. Once it is approved, please confirm that the edit clearly depicts what you need. – hfontanez Jan 28 '21 at 17:41
  • 1
    What have you tried so far? Were you able to open a file in Java, and read a single Excel cell for example? – Koray Tugay Jan 28 '21 at 20:35
  • I can write in completly new file, or create new file, as I want. My goal is add data to existing row. Read the row and then decide weather the data shoud be append or I need to check next row. I do not use 2 files, because I need better solution. I can put all row cells in a list and add new ones and write it in the second file, but I think that there is simple solution. – Gaj Julije Jan 28 '21 at 20:40
  • 2
    @GajJulije this is not a good reason at all. If that was the case, add every tag under the sun to reach even more people. Tags are intended to reach an audience with knowledge of the subject in question (see https://stackoverflow.com/help/tagging). Assume that people that know Selenium know nothing about Excel or Apache POI and don't bother them with the question. – hfontanez Jan 28 '21 at 21:04

1 Answers1

2

I really think Apache Poi is the best solution when it comes to managing excels in Java. You might want to have a look at these examples provided by Apache Poi itself about this topic (the url may change slightly over time). This article also may provide an hint for the solution you're asking for.

You can create a new Workbook (the Java Object representing your excel) using WorkbookFactory as follows:

Workbook workbook = WorkbookFactory.create(new FileInputStream(excelFilePath));

where excelFilePath is (obviously) the Path of the excel file you want to update.

You can now do whatever you want with your Workbook, hurray! You can both read and change all its content and (eventually) write new one! Note that all the changes to your Workbook are NOT actually going to affect your excel file. You're editing the Workbook Java Object, not the actual excel file. In a sense, your Workbook is initially created based on your excel file content, then it is totally independent from it.

Once you're done editing your Workbook, you can save it overriding your initial excel file (in a way, you're now updating your excel file with all your changes) as follows:

FileOutputStream outputStream = new FileOutputStream(excelFilePath);
workbook.write(outputStream);
workbook.close();
outputStream.close();

and you're done! Simple and effective!

Here it is some code that may suit your needs:

public static void main(String[] args) throws EncryptedDocumentException, IOException {
    
    // Step 1: load your excel file as a Workbook
    
    String excelFilePath = "D:\\Desktop\\testExcel.xlsx";
    Workbook workbook = WorkbookFactory.create(new FileInputStream(excelFilePath));
    
    // Step 2: modify your Workbook as you prefer
    
    Iterator<Sheet> sheetIterator = workbook.sheetIterator(); // Getting an iterator for all the sheets
    while (sheetIterator.hasNext()) {
        Iterator<Row> rowIterator = sheetIterator.next().rowIterator(); // Getting an iterator for all the rows (of current sheet)
        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            // Put here your internal logic to understand if the row needs some changes!
            int cellsn = row.getLastCellNum() == -1 ? 0 : row.getLastCellNum();
            for (int j = cellsn ; j < cellsn + 32 ; ++j) {
                row.createCell(j, CellType.STRING).setCellValue("New column after the last existing one n°" + (j - cellsn + 1));
            }
        }
    }
    
    // Step 3: update the original excel file with all your amazing changes!
    
    FileOutputStream outputStream = new FileOutputStream(excelFilePath);
    workbook.write(outputStream);
    workbook.close();
    outputStream.close();
}

Some final notes:

Do not call the method create(java.io.File file) instead of create(java.io.InputStream inp) while using WorkbookFactory and creating your Workbook, it will lead to problems when saving your file as it's discussed on this post.

I really don't know the reason why you initially add the tag "selenium" to your question but if you're thinking to use some spider-code to "manually" open and edit your excel file, please don't. This solution is as horrible as HSSF is (did you get the joke?).

If you're using .xlsx excel files, you may want to use Apache Poi XSSF objects (as XSSFWorkbook, XSSFRow and XSSFCell). More about XSSF vs HSSF on this post.

Finally, here it is the explicit list of all libreries needed in order for my code to run (they're a lot, do not panic): Apache Poi 4.1.2, Apache Poi Ooxml 4.1.2, Apache Poi Ooxml Schemas 4.1.2, XmlBeans, Commons Codec, Commons Collections4, Commons Compress and Commons Math3. If you're using Maven, just add to your dependencies file the following lines:

<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>4.1.2</version>
</dependency>

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

And that's all, hope it helps! Good work!

VinceLomba
  • 398
  • 2
  • 8
  • 18
  • Thanks men. Great answer with lot of details. I will try it and let you know did it help. But I think it will 99%. – Gaj Julije Jan 29 '21 at 09:50
  • 1
    You're welcome! I'm now editing it with a little more details. Please, make sure to mark my answer as the accepted one if it answers your question! – VinceLomba Jan 29 '21 at 10:00
  • 1
    Had to make some changes, but it is related with my program needs. Thanks one more time for the answer. – Gaj Julije Feb 01 '21 at 07:35