POI:将行附加到现有工作簿

时间:2013-09-13 20:22:46

标签: apache-poi

使用XSSFWorkbook,是否可以将行附加到现有工作表?我正在做多次写入(由于一个错误,这是一个要解决的PITA),虽然我可以多次写出新的工作表,但似乎我无法追加。

我目前正在做的是以下内容:

  1. 将表格阅读到我的工作簿。
  2. 加载工作簿。
  3. 将行附加到内存中的工作簿
  4. 再次写出来。
  5. 4似乎不起作用,完全忽略它!

    我知道SXSSFWorkbook存在,但是尝试将我现有的XSSFWorkbook转换为流式工作簿会在写入时产生损坏。

    是否有可能解决这个问题?

    更新:根据建议更改了代码,但收到了流关闭错误。

    代码:(物理行正确返回,但没有写出来)

    private void writeToSheetMultipleTimes(SXSSFWorkbook wb,
                ReportTemplateStructure appA, File wbFile)
        {
    
            Sheet sheet = wb.getSheetAt(0);
    
            log.info("Attempting multi-write to sheet: " + sheet.getSheetName());
            for(int i = 0; i < 10; i++)
            {
    
                Row row = sheet.getRow(i);
    
                if (row == null) {
                   row = sheet.createRow(i);
                }
                Cell cell = row.getCell(0, Row.CREATE_NULL_AS_BLANK);
    
    
    
                cell.setCellValue("Written value:" + i);
    
                int numRows = sheet.getPhysicalNumberOfRows();
    
                log.info("Current row count: " + numRows);
    
                try{
                    XSSFWorkbook xssfBook = (XSSFWorkbook)writeOutAndReadBack(wb);
                    wb.dispose();
    
                    wb = new SXSSFWorkbook(xssfBook);
                } catch (Exception e)
                {
                    log.error("Unable to perform multiple write to same sheet", e);
                }
            }
    
    
        }
    
       public Workbook writeOutAndReadBack(Workbook wb) {
            if(!(wb instanceof SXSSFWorkbook)) {
                throw new IllegalArgumentException("Expected an instance of SXSSFWorkbook");
            }
    
            Workbook result;
            try {
                FileOutputStream baos = new FileOutputStream(streamingWorkBookFile);
                wb.write(baos);
                InputStream is = new FileInputStream(streamingWorkBookFile);
                result = new XSSFWorkbook(is);
    
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return result;
        }  
    

2 个答案:

答案 0 :(得分:2)

您似乎总是对工作表0进行更改,但您每次都在调用createRow。如果那里已经存在某些东西,例如你的第二次传球,这将不会顺利!您需要每次都添加一个新的工作表,或者首先检查Row是否存在getRow(int)调用,只有在它为空时才会创建。

如果我们查看您的代码段:

Sheet sheet = wb.getSheetAt(0);
for(int i = 0; i < 10; i++)
{
    Row row = sheet.createRow(i);
    Cell cell = row.createCell(0);

那应该是:

Sheet sheet = wb.createSheet();
for(int i = 0; i < 10; i++)
{
    Row row = sheet.createRow(i);
    Cell cell = row.createCell(0);

或者您应首先检查并仅创建缺少的行/单元格,例如

Sheet sheet = wb.getSheetAt(0);
for(int i = 0; i < 10; i++)
{
    Row row = sheet.getRow(i);
    if (row == null) {
       row = sheet.createRow(i);
    }
    Cell cell = row.getCell(0, Row.CREATE_NULL_AS_BLANK);

答案 1 :(得分:0)

您可以使用getPhysicalNumberOfRows()类中的XSSFSheet方法获取上次更新的行号。现在通过递增此值来附加新数据来创建一个新行。