在 POI 中复制 Excel 工作表

发布于 2024-07-19 17:37:18 字数 200 浏览 15 评论 0原文

有谁知道使用 POI 将工作表从一个工作簿复制到另一个工作簿的方法吗? Workbook类有一个cloneSheet方法,但似乎无法将克隆工作表插入到新工作簿中?

如果没有 API 可以轻松完成此操作,是否有人拥有将所有数据(样式、列宽、数据等)从一张纸复制到另一张纸的代码?

jxls 有复制工作表的方法,但在工作簿之间复制时它们不起作用。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

苦妄 2024-07-26 17:37:18

我已经用 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();
    }
}

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();
    }
}
吻风 2024-07-26 17:37:18

我为 NPOI 创建了一个工作项: http://npoi.codeplex.com/WorkItem /View.aspx?WorkItemId=6057

更新:该工作项在 NPOI 2.0 中实现。 您可以从 https://npoi.codeplex.com/releases/view/112932< 下载 NPOI 2.0 /a>

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

云仙小弟 2024-07-26 17:37:18

这是我将工作表从一个工作簿复制到另一个工作簿的实现。 这个解决方案对我有用。 如果工作表没有表格等,则此代码将起作用。如果工作表包含简单文本(字符串、布尔值、整数等)、公式,则此解决方案将起作用。

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

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 as is without leaving anything, the process of elimination works better in this case and faster than 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();
路还长,别太狂 2024-07-26 17:37:18

如果您使用的是 Java POI 库,最好的方法是将电子表格加载到内存中,然后创建一个新电子表格并写入要复制的每一条记录...这不是最好的方法,但可以完成复制功能。 ..

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...

嘿嘿嘿 2024-07-26 17:37:18

我花了大约一周的时间用 POI 来做这件事(使用 coderanch 上的最新代码) - 请注意,代码有缺陷(使用 TreeSet 存在问题,您需要用 HashMap 替换它),但即使在修复之后它会在公式上崩溃。

虽然有可能做到这一点,但必须依赖破解的代码是一个可怕的提议。

根据您的需求/预算,您可能需要考虑硬着头皮付费购买 aspose - http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets- inside-and- Between-workbooks.html

它成功复制了工作表,包括格式、公式和内容。 保护规则。 我在 130 秒内完成了 300 张。 (300 x 90kb 工作簿,编译为一本 15mb 工作簿)。 该演示是免费的,它只是在工作簿中添加了一张附加表,提醒您购买许可证。

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.

荭秂 2024-07-26 17:37:18

最好的方法是打开文件并加载它。
如果您想要源 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();
    }

这应该有助于澄清

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文