在POI中复制Excel工作表
有谁知道一种方法将工作表从一个工作簿复制到另一个使用兴趣点? Workbook类有一个cloneSheet方法,但似乎无法将克隆的表单插入到新的工作簿中?
如果没有一个API可以很容易的完成这个任务,那么是否有人有把所有数据(样式,列宽,数据等等)从一张表复制到另一张的代码?
jxls有复制工作表的方法,但在工作簿之间复制时不起作用。
我用poi实现了一些function。 请参阅代码供您参考。
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(); } }
我为NPOI创build了一个工作项目: http ://npoi.codeplex.com/WorkItem/View.aspx?WorkItemId= 6057 。
更新:工作项目在NPOI 2.0中实施。 您可以从https://npoi.codeplex.com/releases/view/112932下载NPOI 2.0
如果您正在使用Java POI库,最好的方法是将电子表格加载到内存中,然后创build一个新的并写入您想要复制的每个logging…不是最好的方法,而是实现复制function。 ..
我花了大约一周的时间来使用POI(使用coderanch上的最新代码)来做这件事 – 要警告代码是有缺陷的(使用TreeSet时需要使用HashMapreplace它),但即使在修复它崩溃的公式。
虽然有可能做到这一点是不得不依靠被黑客入侵的代码的可怕命题。
根据您的需求/预算,您可能需要考虑咬子弹和支付aspose – http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets-within -and-之间-workbooks.html
它成功复制工作表,包括格式,公式和保护规则。 我在130秒内做了300张。 (300 x 90kb的工作簿,编译成一个15MB的工作簿)。 该演示是免费的,它只是将一张额外的表格放入工作簿,提醒您购买许可证。
这是我从一个工作簿复制到另一个工作簿的实现。 这个解决scheme适用于我。 这个代码将工作,如果工作表没有表等。如果工作表包含简单的文本(string,布尔,int等),公式,这个解决scheme将工作。
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();