Копирование таблиц Excel в POI - PullRequest
21 голосов
/ 11 мая 2009

Кто-нибудь знает способ копирования рабочего листа из одной рабочей книги в другую с использованием POI? В классе Workbook есть метод cloneSheet, но, похоже, нет возможности вставить клонированный лист в новую книгу?

Если не существует API для этого, есть ли у кого-нибудь код для копирования всех данных (стили, ширины столбцов, данные и т. Д.) С одного листа на другой?

В jxls есть методы для копирования листов, но они не работают при копировании между книгами.

Ответы [ 6 ]

5 голосов
/ 07 ноября 2012

Я реализовал некоторые функции с помощью poi. пожалуйста, смотрите код для вашей справки.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelReadAndWrite {

    public static void main(String[] args) throws IOException {
        ExcelReadAndWrite excel = new ExcelReadAndWrite();
        excel.process("D:/LNN/My Workspace/POI/src/tables.xls");
    }

    public void process(String fileName) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName));
        HSSFWorkbook workbook = new HSSFWorkbook(bis);
        HSSFWorkbook myWorkBook = new HSSFWorkbook();
        HSSFSheet sheet = null;
        HSSFRow row = null;
        HSSFCell cell = null;
        HSSFSheet mySheet = null;
        HSSFRow myRow = null;
        HSSFCell myCell = null;
        int sheets = workbook.getNumberOfSheets();
        int fCell = 0;
        int lCell = 0;
        int fRow = 0;
        int lRow = 0;
        for (int iSheet = 0; iSheet < sheets; iSheet++) {
            sheet = workbook.getSheetAt(iSheet);
            if (sheet != null) {
                mySheet = myWorkBook.createSheet(sheet.getSheetName());
                fRow = sheet.getFirstRowNum();
                lRow = sheet.getLastRowNum();
                for (int iRow = fRow; iRow <= lRow; iRow++) {
                    row = sheet.getRow(iRow);
                    myRow = mySheet.createRow(iRow);
                    if (row != null) {
                        fCell = row.getFirstCellNum();
                        lCell = row.getLastCellNum();
                        for (int iCell = fCell; iCell < lCell; iCell++) {
                            cell = row.getCell(iCell);
                            myCell = myRow.createCell(iCell);
                            if (cell != null) {
                                myCell.setCellType(cell.getCellType());
                                switch (cell.getCellType()) {
                                case HSSFCell.CELL_TYPE_BLANK:
                                    myCell.setCellValue("");
                                    break;

                                case HSSFCell.CELL_TYPE_BOOLEAN:
                                    myCell.setCellValue(cell.getBooleanCellValue());
                                    break;

                                case HSSFCell.CELL_TYPE_ERROR:
                                    myCell.setCellErrorValue(cell.getErrorCellValue());
                                    break;

                                case HSSFCell.CELL_TYPE_FORMULA:
                                    myCell.setCellFormula(cell.getCellFormula());
                                    break;

                                case HSSFCell.CELL_TYPE_NUMERIC:
                                    myCell.setCellValue(cell.getNumericCellValue());
                                    break;

                                case HSSFCell.CELL_TYPE_STRING:
                                    myCell.setCellValue(cell.getStringCellValue());
                                    break;
                                default:
                                    myCell.setCellFormula(cell.getCellFormula());
                                }
                            }
                        }
                    }
                }
            }
        }
        bis.close();
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("workbook.xls", true));
        myWorkBook.write(bos);
        bos.close();
    }
}
3 голосов
/ 05 мая 2010

Я создал рабочий элемент для НКО: http://npoi.codeplex.com/WorkItem/View.aspx?WorkItemId=6057.

Обновление: Рабочий элемент реализован в NPOI 2.0. Вы можете скачать NPOI 2.0 с https://npoi.codeplex.com/releases/view/112932

2 голосов
/ 31 мая 2010

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

1 голос
/ 25 января 2011

Я потратил около недели усилий на то, чтобы сделать это с помощью POI (используя последний код на coderanch) - предупреждаю, что код имеет недостатки (есть проблема с использованием TreeSet, когда вам нужно заменить его на HashMap), но даже после исправления ошибки в формулах.

Хотя это может быть возможным, это страшное предложение - полагаться на взломанный код.

В зависимости от ваших потребностей / бюджета, вы можете подумать о том, чтобы укусить пулю и заплатить за это - http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets-within-and-between-workbooks.html

Он успешно скопировал листы, включая форматирование, формулы и правила защиты. Я сделал 300 листов за 130 секунд. (300 x 90 КБ рабочих книг, собранных в одну 15 МБ рабочую книгу). Демонстрация бесплатна, она просто помещает дополнительный лист в рабочую книгу, напоминая вам о необходимости купить лицензию.

0 голосов
/ 16 октября 2018

Лучший способ - открыть файл и загрузить его. Если вам нужен какой-либо конкретный лист из исходного файла Excel, вам просто нужно удалить лист, который не соответствует предполагаемому листу.

попробуйте это:

     FileInputStream fis=new FileInputStream("D:\\SourceExcel.xls");
     Workbook wb=WorkbookFactory.create(fis);

    for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
            if (!wb.getSheetName(i).contentEquals("SheetNameWhichwantToRetain")) //This is a place holder. You will insert your logic here to get the sheets that you want.  
                wb.removeSheetAt(i); //Just remove the sheets that don't match your criteria in the if statement above               
    }
    FileOutputStream fos = new FileOutputStream(new File("D:\\DestinationFileName.xls"));
    wb.write(fos);
    fos.close();
    System.out.println("file is copied in a new file at destination :"+"D:\\DestinationFileName.xls");
    }
    catch(Exception e){
        e.printStackTrace();
    }

Это должно помочь уточнить

0 голосов
/ 21 декабря 2016

Это моя реализация копирования листов из одной рабочей книги в другую. Это решение работает для меня. Этот код будет работать, если на листах нет таблиц и т. Д. Если листы содержат простой текст (String, boolean, int и т. Д.), Формулы, это решение будет работать.

Workbook oldWB = new XSSFWorkbook(new FileInputStream("C:\\input.xlsx"));
Workbook newWB = new XSSFWorkbook();
CellStyle newStyle = newWB.createCellStyle(); // Need this to copy over styles from old sheet to new sheet. Next step will be processed below
Row row;
Cell cell;
for (int i = 0; i < oldWB.getNumberOfSheets(); i++) {
    XSSFSheet sheetFromOldWB = (XSSFSheet) oldWB.getSheetAt(i);
    XSSFSheet sheetForNewWB = (XSSFSheet) newWB.createSheet(sheetFromOldWB.getSheetName());
    for (int rowIndex = 0; rowIndex < sheetFromOldWB.getPhysicalNumberOfRows(); rowIndex++) {
        row = sheetForNewWB.createRow(rowIndex); //create row in this new sheet
        for (int colIndex = 0; colIndex < sheetFromOldWB.getRow(rowIndex).getPhysicalNumberOfCells(); colIndex++) {
            cell = row.createCell(colIndex); //create cell in this row of this new sheet
            Cell c = sheetFromOldWB.getRow(rowIndex).getCell(colIndex, Row.CREATE_NULL_AS_BLANK ); //get cell from old/original WB's sheet and when cell is null, return it as blank cells. And Blank cell will be returned as Blank cells. That will not change.
                if (c.getCellType() == Cell.CELL_TYPE_BLANK){
                    System.out.println("This is BLANK " +  ((XSSFCell) c).getReference());
                }
                else {  //Below is where all the copying is happening. First It copies the styles of each cell and then it copies the content.              
                CellStyle origStyle = c.getCellStyle();
                newStyle.cloneStyleFrom(origStyle);
                cell.setCellStyle(newStyle);            

                 switch (c.getCellTypeEnum()) {
                    case STRING:                            
                        cell.setCellValue(c.getRichStringCellValue().getString());
                        break;
                    case NUMERIC:
                        if (DateUtil.isCellDateFormatted(cell)) {                             
                            cell.setCellValue(c.getDateCellValue());
                        } else {                              
                            cell.setCellValue(c.getNumericCellValue());
                        }
                        break;
                    case BOOLEAN:

                        cell.setCellValue(c.getBooleanCellValue());
                        break;
                    case FORMULA:

                        cell.setCellValue(c.getCellFormula());
                        break;
                    case BLANK:
                        cell.setCellValue("who");
                        break;
                    default:
                        System.out.println();
                    }
                }
            }
        }

    }
    //Write over to the new file
    FileOutputStream fileOut = new FileOutputStream("C:\\output.xlsx");
    newWB.write(fileOut);
    oldWB.close();
    newWB.close();
    fileOut.close();

Если вы хотите скопировать полные листы, не добавляя и не добавляя ничего. Я думаю, что процесс исключения работает лучше и быстрее, чем приведенный выше код. И вам не нужно беспокоиться о потере формул, рисунков, таблиц, стилей, шрифтов и т. Д.

XSSFWorkbook wb = new XSSFWorkbook("C:\\abc.xlsx");
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
        if (!wb.getSheetName(i).contentEquals("January")) //This is a place holder. You will insert your logic here to get the sheets that you want.  
            wb.removeSheetAt(i); //Just remove the sheets that don't match your criteria in the if statement above               
}
FileOutputStream out = new FileOutputStream(new File("C:\\xyz.xlsx"));
wb.write(out);
out.close();
...