#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:
Здесь некоторые столбцы являются дополнительными в 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. Да, но я также хочу заголовок всех