Объединить несколько файлов Excel в один файл Excel с помощью Apache POI Java

#java #excel #merge #apache-poi #bulkinsert

#java #excel #объединить #apache-poi #bulkinsert

Вопрос:

У меня есть 100 файлов Excel, и я хочу объединить их все в один файл Excel. Здесь, в моем примере, у меня есть 2 файла Excel, и я хочу объединить их в один. Я не могу этого сделать. Я использую Apache POI API. В одной книге Excel также может быть более одного листа, поэтому я хочу также перебирать листы каждой книги. Я пытался и исследовал, но я получил эту ссылку, и она у меня не работает https://dev.to/eiceblue/merge-excel-files-in-java-2lo2#:~:text=A quick way to merge,data table into another worksheet .

Пожалуйста, помогите мне здесь.

 package com.cas.ExcelTest;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

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

public class Combine {

    public static void main(String args[]) {
        
        String[] files = new String[] {"Test2.xlsx","Test3.xlsx"};
        XSSFWorkbook workbook = new XSSFWorkbook();     
        try {
            for (int f = 0; f < files.length; f  ) {    
                String file = files[f];
                FileInputStream inputStream = new FileInputStream(file);
                XSSFWorkbook tempWorkbook = new XSSFWorkbook(inputStream);
                          
                int numOfSheets = tempWorkbook.getNumberOfSheets();
                    
                for (int i = 0; i < numOfSheets; i  ) {
                    XSSFSheet tempSheet = tempWorkbook.getSheetAt(i);
                    String newSheetName = "" f "" tempSheet.getSheetName();
                    XSSFSheet sheet = workbook.createSheet(newSheetName);
                    Iterator<Row> itRow = tempSheet.rowIterator();
                
                    while(itRow.hasNext()) {
                        Row tempRow = itRow.next();
                        XSSFRow row = sheet.createRow(tempRow.getRowNum());
                        Iterator<Cell> itCell = tempRow.cellIterator();
                    
                        while(itCell.hasNext()) {
                            Cell tempCell = itCell.next();
                            XSSFCell cell = row.createCell(tempCell.getColumnIndex());
                        
                        switch (tempCell.getCellType()) {
                        case NUMERIC:
                            cell.setCellValue(tempCell.getNumericCellValue());
                            break;
                        case STRING:
                            cell.setCellValue(tempCell.getStringCellValue());
                            break;
                        case BLANK:
                            break;
                        case BOOLEAN:
                            break;
                        case ERROR:
                            break;
                        case FORMULA:
                            cell.setCellValue(tempCell.getNumericCellValue());
                            break;
                        case _NONE:
                            break;
                        default:
                            break;
                    }
                        }       
                    }       
                }
            }
        } catch (IOException ex1) {
            System.out.println("Error reading file");
            ex1.printStackTrace();
        }
            
        try (FileOutputStream outputStream = new FileOutputStream("result.xlsx")) {
            workbook.write(outputStream);
        }
        catch(Exception ex) {
            System.out.println("Something went wrong");
        }
    }
}
  

Мои файлы Excel:

Test2.xlsx

Test3.xlsx

Здесь некоторые столбцы являются дополнительными в Test3.xlsx и в обоих файлах, как вы можете видеть в строке заголовка, это вся строка, но после этого она имеет числовые значения.

Ответ №1:

Здесь у вас есть приблизительный код, который вам нужен, отформатируйте его, извлеките функциональные возможности из методов и проверьте именование листов.

 String[] files = new String[] {"Test2.xlsx","Test3.xlsx"};
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = createSheetWithHeader(workbook);
    
try {
    for (int f = 0; f < files.length; f  ) {
        String file = files[f];
        FileInputStream inputStream = new FileInputStream(file);
        XSSFWorkbook tempWorkbook = new XSSFWorkbook(inputStream);
            
        int numOfSheets = tempWorkbook.getNumberOfSheets();
            
        for (int i = 0; i < numOfSheets; i  ) {
            XSSFSheet tempSheet = tempWorkbook.getSheetAt(i);
                
            int indexLastDataInserted = sheet.getLastRowNum();
            int firstDataRow = getFirstDataRow(tempSheet);
                                
            Iterator<Row> itRow = tempSheet.rowIterator();
            
            while(itRow.hasNext()) {
                Row tempRow = itRow.next();
                
                if (tempRow.getRowNum() >= firstDataRow) {
                    XSSFRow row = sheet.createRow(indexLastDataInserted   1);
                    
                    Iterator<Cell> itCell = tempRow.cellIterator();
                    
                    while(itCell.hasNext()) {
                        Cell tempCell = itCell.next();
                        XSSFCell cell = row.createCell(tempCell.getColumnIndex());
                        //At this point you will have to set the value of the cell depending on the type of data it is
                        switch (tempCell.getCellType()) {
                            case NUMERIC:
                                cell.setCellValue(tempCell.getNumericCellValue());
                                break;
                            case STRING:
                                cell.setCellValue(tempCell.getStringCellValue());
                                break;
                            /**
                             * Add your other types, here is your problem!!!!!
                             */
                        }
                    }
                }                   
            }
        }
    } 
}catch (IOException ex1) {
    System.out.println("Error reading file");
    ex1.printStackTrace();
}
    
try (FileOutputStream outputStream = new FileOutputStream("result.xlsx")) {
    workbook.write(outputStream);
}
  

Функция для получения первой строки данных (необходима, чтобы избежать необходимости вводить вручную, где заканчивается заголовок каждого Excel):

 /**
 * If the tab has a filter, it returns the row index of the filter   1, otherwise it returns 0
 * @param tempSheet
 * @return index of first data row
 */
public static Integer getFirstDataRow(XSSFSheet tempSheet) {
    Integer result = 0;
    Boolean isAutoFilter = tempSheet.getCTWorksheet().isSetAutoFilter();
    
    if (isAutoFilter) {
        String autoFilterRef = tempSheet.getCTWorksheet().getAutoFilter().getRef();
        
        result = new CellReference(autoFilterRef.substring(0, autoFilterRef.indexOf(":"))).getRow()   1;
    }
    return resu<
}
  

Создайте лист с заголовком в методе:

 public static XSSFSheet createSheetWithHeader(XSSFWorkbook workbook){
    XSSFSheet sheet = workbook.createSheet("NEW_SHEET_NAME");

    //Implement the header
    [...]

    return sheet;
}
  

Комментарии:

1. Здесь в обоих моих файлах некоторые столбцы одинаковы, а некоторые отличаются, но в этом цикле while, когда я устанавливаю значения ячеек, я делаю это в соответствии с test2.xlsx но это не сработало для другого файла, поскольку некоторые из его столбцов отличаются, так какое же решение здесь? @JLazar0

2. Я не очень хорошо понимаю проблему, это фрагмент концептуального кода, который вам нужно выполнить, я думаю, проблемы могут подсказать вам, где находится комментарий, что если тип данных не текст, это выдает ошибку, но, как я указываю, вы должны завершить его в этой точке. Используемая версия POI — 4.1.0, можете ли вы приложить пример ошибок, которые вас подводят, или трассировку журнала, чтобы узнать, связано ли это с типом данных?

3. Взгляните на мой вопрос, теперь я добавил свои файлы Excel @JLazar0

4. Хорошо, что вам нужно, это собрать все данные, которые находятся под фильтрами, в одной таблице?

5. Да, но я также хочу заголовок всех