2009-05-11 199 views
21

¿Alguien sabe de un medio para copiar una hoja de cálculo de un libro de trabajo a otro utilizando un PDI? La clase Workbook tiene un método cloneSheet, pero parece que no se puede insertar una hoja clonada en un nuevo libro de trabajo.Copia de hojas de trabajo de Excel en POI

Si no hay una API para hacer esto fácilmente, ¿alguien tiene el código para copiar todos los datos (estilos, anchuras de columna, datos, etc.) de una hoja a otra?

El jxls tiene métodos para copiar hojas, pero no funcionan al copiar entre libros.

+1

este [link] (http://www.coderanch.com/t/420958/open-source/Copying-sheet-excel-file-another) debería ser útil: – hkansal

+0

@hkansal ese enlace que encontré cuando estaba buscando en Google. Me enfrenté a un problema con el código dado en ese enlace, cuando la celda está agrupada en columnas como A1: A4 muestra un error como una superposición fusionada Región, no puedo publicar una respuesta en ese enlace. Es realmente bueno. –

Respuesta

2

Si está utilizando la biblioteca POI de Java, lo mejor sería cargar la hoja de cálculo en la memoria ,,, luego crear una nueva y escribir cada uno de los registros que desea copiar. No es la mejor manera, pero cumple la función de copia ...

1

Puse alrededor de una semana de esfuerzo en hacer esto con POI (usando el último código en coderanch) - se advirtió que el código es defectuoso (hay un problema con usando TreeSet donde necesita reemplazar eso con un HashMap), pero incluso después de arreglar eso falla en las fórmulas.

Si bien puede ser posible, es una proposición aterradora tener que depender del código pirateado.

dependiendo de sus necesidades/presupuesto es posible que desee considerar la posibilidad de morder la bala y pagar por Aspose - http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets-within-and-between-workbooks.html

It hojas copiadas con éxito incluyendo el formato, fórmulas, & las normas de protección. Hice 300 hojas en 130 segundos. (Libros de trabajo de 300 x 90 kb, compilados en un libro de trabajo de 15 mb). La demostración es gratuita, solo pone una hoja adicional en el libro de trabajo que le recuerda que compre una licencia.

5

he implementado algunas funciones con poi. por favor vea el código para su referencia.

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

Esta es mi implementación de copiar hojas de un libro de trabajo a otro. Esta solución funciona para mí. Este código funcionará si las hojas no tienen tablas, etc. Si las hojas contienen texto simple (String, boolean, int, etc.), esta solución funcionará.

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

Si su requisito es copiar hojas completas sin salir ni agregar nada. Creo que el proceso de eliminación funciona mejor y más rápido que el código anterior. Y usted no tiene que preocuparse de perder fórmulas, dibujos, tablas, estilos, fuentes, 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(); 
Cuestiones relacionadas