Copying Excel Worksheets in POI

為{幸葍}努か 提交于 2019-12-21 03:33:07

问题


Does anyone know of a means to copy a worksheet from one workbook to another using POI? The Workbook class has a cloneSheet method, but there doesn't seem to be able to insert a cloned sheet into a new workbook?

If there isn't an API to do this easily, does anyone have the code to copy all of the data (styles, column widths, data, etc) from one sheet to another?

The jxls has methods to copy sheets, but they don't work when copying between workbooks.


回答1:


i have implemented some functionality with poi. please see the code for your reference.

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();
    }
}



回答2:


I created a workitem for NPOI: http://npoi.codeplex.com/WorkItem/View.aspx?WorkItemId=6057.

Update: The workitem is implemented in NPOI 2.0. You can download NPOI 2.0 from https://npoi.codeplex.com/releases/view/112932




回答3:


If you are using the Java POI library the best would be to load the Spreadsheet into memory,,, then create a new one and write each one of the records you want to copy... not the best way but acomplishes the copy function...




回答4:


I put about a week of effort into doing this with POI (using the latest code on coderanch) - be warned that the code is flawed (there's an issue with using TreeSet where you need to replace that with a HashMap), but even after fixing that it crashes on formulas.

While it may be possible to do it's a scary proposition to have to rely on hacked up code.

Depending on your needs/budget you may want to consider biting the bullet and paying for aspose - http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets-within-and-between-workbooks.html

It successfully copied sheets including formatting, formulas, & protection rules. I did 300 sheets in 130 seconds. (300 x 90kb workbooks, compiled into one 15mb workbook). The demo is free, it just puts an additional sheet into the workbook reminding you to buy a license.




回答5:


This is my implementation of copying sheets from one workbook to another. This solution works for me. This code will work if the sheets don't have tables, etc. If the sheets contain simple text (String, boolean, int etc), formulas, this solution will work.

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();

If your requirement is to copy full sheets without leaving or adding anything. I think The process of elimination works better and faster then the above code. And you don't have to worry about losing formulas, drawings, tables, styles, fonts, etc.

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();



回答6:


The best way is to open the file and load it. If you want any of the specific sheets from the source Excel file, then you just need to remove the sheet that does not match the intended Sheet.

try this:

     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();
    }

This should help clarify



来源:https://stackoverflow.com/questions/848212/copying-excel-worksheets-in-poi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!