2014-09-03 35 views
3

我有使用Apache POI库(我使用旧的Excel文件的HSSF前缀类)导出/导入excel文件(.xls)的java程序。
Java POI输出时忽略导出到空行的excel

我的Excel格式是:
第1行:标题
第2行:空
第3行:表与报头和内容

比方说我的表有5行,包括头,因此,总共7排。 我正在将数据导出到excel文件,文件大小为6k。 没有改变文件中的任何东西我正在导入它,并在调试导入时,我意识到我的行数是6!这意味着它由于某种原因忽略了空行,这是我不明白的。

接下来的情况下,我导出文件打开它与MS Excel保存它,文件大小更改为24K。 我执行导入,它的工作原理,行的总大小再次是7。
出口和进口的代码开始低于:

public static TempFile createExcelFile(String sheetTitle, String title, String headerSummary, List<String> header, List<LinkedHashMap<String, String>> data) 
{ 
    TempFile result = new TempFile(FileKeyFactory.getFileKey(ExcelReporter.class).getFullPathKey()); 
    HSSFWorkbook wb = new HSSFWorkbook(); 
    HSSFSheet spreadSheet; 
    DataFormat format = null; 
    int rowIndex = 0; 

    // Get a DataFormat object and use it to create a CellStyle object 
    // with the following format set for the cells @. The @ or ampersand 
    // sets the format so that the cell will hold text. 
    format = wb.createDataFormat(); 

    if (sheetTitle != null) 
    { 
     spreadSheet = wb.createSheet(sheetTitle); 
    } 
    else 
    { 
     spreadSheet = wb.createSheet(); 
    } 

    if (title != null) 
    { 
     // Title 
     HSSFFont titleFont = wb.createFont(); 
     titleFont.setFontHeightInPoints((short) 14); 
     titleFont.setItalic(true); 
     HSSFRow titleRow = spreadSheet.createRow(rowIndex++); 
     HSSFCell cell = titleRow.createCell(0); 
     cell.setCellValue(title); 
     cell.getCellStyle().setFont(titleFont); 
     spreadSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 100)); 
    } 
    else 
    { 
     spreadSheet = wb.createSheet(); 
    } 

    HSSFCellStyle style = wb.createCellStyle(); 
    style.setDataFormat(format.getFormat("@")); 

    if (headerSummary != null) 
    { 
     HSSFFont headerFont = wb.createFont(); 
     headerFont.setFontHeightInPoints((short) 9); 
     headerFont.setItalic(false); 

     HSSFCellStyle headerCellStyle = wb.createCellStyle(); 
     headerCellStyle.setDataFormat(format.getFormat("@")); 
     headerCellStyle.setFont(headerFont); 
     headerCellStyle.setWrapText(true); 

     HSSFRow headerRow = spreadSheet.createRow(rowIndex++); 
     HSSFCell headerCell = headerRow.createCell(0); 

     headerCell.setCellValue(headerSummary); 
     headerCell.setCellStyle(headerCellStyle); 
     //increase row height to accommodate two lines of text 
     headerRow.setHeightInPoints((9 * spreadSheet.getDefaultRowHeightInPoints())); 

     //adjust column width to fit the content 
     spreadSheet.autoSizeColumn((short) 1); 
     spreadSheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 100)); 
    } 


    /* 
    * Data table header 
    */ 
    HSSFRow dateRow = spreadSheet.createRow(rowIndex++); 
    Calendar calendar = Calendar.getInstance(); 
    HSSFCreationHelper createHelper = wb.getCreationHelper(); 
    CellStyle cellStyle = wb.createCellStyle(); 
    cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("m/d/yy h:mm")); 
    HSSFCell cell = dateRow.createCell(0); 
    cell.setCellValue("Created: " + DateParser.toString(calendar, DateParser.MONTH_WORD_DATE_FORMAT)); 
    cell.setCellStyle(cellStyle); 

    HSSFFont headerTableFont = wb.createFont(); 
    headerTableFont.setFontHeightInPoints((short) 10); 
    headerTableFont.setColor(IndexedColors.WHITE.getIndex()); 

    HSSFCellStyle tableHeaderStyle = wb.createCellStyle(); 
    tableHeaderStyle.setDataFormat(format.getFormat("@")); 
    tableHeaderStyle.setBorderRight(HSSFCellStyle.BORDER_MEDIUM); 
    tableHeaderStyle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM); 
    tableHeaderStyle.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM); 
    tableHeaderStyle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM); 
    tableHeaderStyle.setFillForegroundColor(HSSFColor.LIGHT_BLUE.index); 
    tableHeaderStyle.setFont(headerTableFont); 
    tableHeaderStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); 

    HSSFRow tableHeaderRowRow = spreadSheet.createRow(rowIndex++); 

    for (int i = 0; i < header.size(); i++) 
    { 
     HSSFCell ipHeaderCell = tableHeaderRowRow.createCell(i); 
     ipHeaderCell.setCellStyle(tableHeaderStyle); 
     ipHeaderCell.setCellValue(header.get(i)); 
     spreadSheet.autoSizeColumn(i); 
    } 

    /* 
    * ********************** DATA ******************* 
    */ 
    HSSFCellStyle dataCellStyle = wb.createCellStyle(); 
    dataCellStyle.setDataFormat(format.getFormat("@")); 
    dataCellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); 
    dataCellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); 
    dataCellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); 
    dataCellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); 

    //spreadSheet.createRow(rowIndex++); 
    for (LinkedHashMap<String, String> row : data) 
    { 
     HSSFRow currentRow = spreadSheet.createRow(rowIndex++); 
     for (int i = 0; i < header.size(); i++) 
     { 
      HSSFCell dataCell = currentRow.createCell(i); 
      dataCell.setCellStyle(dataCellStyle); 
      dataCell.setCellType(Cell.CELL_TYPE_STRING); 

      String celVal = row.get(header.get(i)); 
      dataCell.setCellValue(celVal); 
     } 
    } 

    // Resize columns automatically. 
    for (int i = 0; i < header.size(); i++) 
    { 
     spreadSheet.setDefaultColumnStyle(i, style); 
     spreadSheet.autoSizeColumn(i); 
    } 

    FileOutputStream resultOutStream = null; 
    try 
    { 
     resultOutStream = new FileOutputStream(result); 
     wb.write(resultOutStream); 
     resultOutStream.flush(); 
    } 
    catch (Exception e) 
    { 
     Logger.ERROR("File path: " + result.getAbsolutePath() + File.separator + result.getName(), e); 
     throw new RuntimeException("File path: " + result.getAbsolutePath() + File.separator + result.getName(), e); 
    } 
    finally 
    { 
     try 
     { 
      if (resultOutStream != null) 
      { 
       resultOutStream.close(); 
      } 
     } 
     catch (Exception ignore) 
     { 

     } 
    } 

    return result; 
} 

public void import() 
{ 
    ... 
    InputStream input = new BufferedInputStream(new FileInputStream(file)); 
    POIFSFileSystem fs = new POIFSFileSystem(input); 
    HSSFWorkbook wb = new HSSFWorkbook(fs); 
    HSSFSheet sheet = wb.getSheetAt(0); 

    Iterator rows = sheet.rowIterator(); 

    rows.next(); // skip title 
    rows.next(); // skip empty row 
    List<String> header = getLine((HSSFRow) rows.next()); 
    ... 
} 

private List<String> getLine(HSSFRow row) 
{ 
    List<String> header = new ArrayList<String>(); 
    Iterator<Cell> cellIterator = row.cellIterator(); 

    while(cellIterator.hasNext()) 
    { 
     HSSFCell cell = (HSSFCell)cellIterator.next(); 
     cell.setCellType(Cell.CELL_TYPE_STRING); 
     header.add(cell.toString()); 
    } 

    return header; 
} 


任何想法,为什么出口和进口之后再空行同时呼吁sheet.rowIterator忽略()?

回答

2

这是预期的行为。来自Javadocs

返回PHYSICAL行的迭代器。意思是第三个元素可能不是第三行,如果说例如第二行是未定义的。

如果你看一下Apache POI documentation on iterating over rows and cells,你会看到更多的细节,描述,并就如何强制所有行迭代的范围内,如果这就是你真正想要的指令一起。您的代码会想是这样的(来自Apache POI文档拍摄)

// Decide which rows to process 
int rowStart = Math.min(15, sheet.getFirstRowNum()); 
int rowEnd = Math.max(1400, sheet.getLastRowNum()); 

for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { 
    Row r = sheet.getRow(rowNum); 
    if (r == null) { 
     // Handle empty row 
     continue; 
    } 

    int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT); 

    for (int cn = 0; cn < lastColumn; cn++) { 
     Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL); 
     if (c == null) { 
     // The spreadsheet is empty in this cell 
     } else { 
     // Do something useful with the cell's contents 
     } 
    } 
} 
+0

的预期和记录行为,这很有趣,虽然我宁愿不限制表格到硬编码的最小/最大行。 – Snow 2014-09-14 14:37:36

+0

我检查了你的代码。我不需要最小/最大值,因为我知道我总是从零开始,而我只需要最后一行,它适用于我。谢谢。 – Snow 2014-09-14 14:48:45

1

我从来没有遇到过这个问题,但我使用sheet.getRow(row)而不是rowIterator()。我想这可能是POI中的rowIterator实现中的一个错误(你应该向他们报告)。

所以能不能请你从改变你的代码:

Iterator rows = sheet.rowIterator(); 
rows.next(); // skip title 
rows.next(); // skip empty row 
List<String> header = getLine((HSSFRow) rows.next()); 

要:

int row = 0; 
++row; // skip title; 
++row; // skip empty row 
List<String> header = getLine((HSSFRow)sheet.getRow(row)); ++row; 

希望工程。

注意:您还应该使用'工作簿','工作表'和'行'而不是'HSSFWorkbook','HSSFSheet'和'HSSFRow'。这将为您节省一些打字费用,并且您的代码将准备就绪,以防您需要一些时间来处理某些XLSX文件!

+0

这不是一个错误,这是非常行迭代器 – Gagravarr 2014-09-10 15:37:26