【问题标题】:CSV generation possible with Apache POI?可以使用 Apache POI 生成 CSV?
【发布时间】:2012-03-13 04:35:58
【问题描述】:

我需要生成 csv 文件,我偶然发现了我们项目本身中的一个模块,它使用 Apache POI 来生成 Excel 表格。所以我想我可以用它来生成csv。所以我问了google兄弟,但他找不到任何可以肯定地说Apache POI可以用于CSV文件生成的东西。我也在检查以下 api,它只讨论 xls 表,而不是任何地方的 csv。有什么想法吗?

http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Workbook.html

【问题讨论】:

    标签: apache-poi


    【解决方案1】:

    Apache Poi 不会为您输出到 CSV。但是,您有几个不错的选择,具体取决于您要写入 csv 的数据类型。

    如果您知道所有单元格都不包含逗号、引号、行尾等 csv 标记,那么您可以遍历数据行并将文本复制到 StringBuffer 并将其发送到常规 java IO。 以下是按照这些思路向 csv 写入 sql 查询的示例:Poi Mailing List: writing CSV

    否则,与其自己弄清楚如何转义特殊字符,不如查看opencsv project

    【讨论】:

    • 我发现如果它是一个简单的 csv 生成,那么它将像下面这样简单......这对我有用。 FileWriter writer = new FileWriter(file.csv); writer.append("columnheading"); writer.append('\n'); writer.append(columnvalue); writer.flush(); writer.close();
    【解决方案2】:

    如果你查看官方网站Apache POI,你可以在那里找到很多例子。还有一个示例展示了如何使用 apache POI 获得 csv 格式的输出。

    ToCSV example

    【讨论】:

    【解决方案3】:

    基本策略:

    1) Apache Commons CSV 是用于写入 CSV 值的标准库。

    2) 但是我们需要自己遍历工作簿,然后在每个单元格值上调用 Commons CSV 的打印机,并在每行的末尾添加一个换行符。不幸的是,这是自定义代码,它不会在 XSSF 中自动使用。但这很简单:

            // In this example we construct CSVPrinter on a File, can also do an OutputStream
            Reader reader = Files.newBufferedReader(Paths.get(SAMPLE_CSV_FILE_PATH));
            CSVPrinter csvPrinter = new CSVPrinter(reader, CSVFormat.DEFAULT);              
    
            if (workbook != null) {
                XSSFSheet sheet = workbook.getSheetAt(0); // Sheet #0
                Iterator<Row> rowIterator = sheet.rowIterator();
                while (rowIterator.hasNext()) {               
                    Row row = rowIterator.next();
                    Iterator<Cell> cellIterator = row.cellIterator();
                    while (cellIterator.hasNext()) {
                        Cell cell = cellIterator.next();
                        csvPrinter.print(cell.getStringCellValue()); // Call Commons CSV here to print
                    }
                    // Newline after each row
                    csvPrinter.println();
                }
    
            }
            // at the end, close and flush CSVPrinter
            csvPrinter.flush();
            csvPrinter.close();
    

    【讨论】:

      【解决方案4】:

      gene b's response 的改进和测试版本是这样的:

      /**
       * Saves all rows from a single Excel sheet in a workbook to a CSV file.
       *
       * @param excelWorkbook path to the Excel workbook.
       * @param sheetNumber   sheet number to export.
       * @param csvFile       CSV file path for output.
       * @throws IOException if failed to read the Excel file or create/write to a CSV file.
       */
      public static void excelToCsv(String excelWorkbook, int sheetNumber, String csvFile) throws IOException {
          try (Workbook workbook = WorkbookFactory.create(new File(excelWorkbook), null, true); // Read-only: true
               BufferedWriter writer = new BufferedWriter(new FileWriter(csvFile));
               CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT)) {
              Sheet sheet = workbook.getSheetAt(sheetNumber);
              DataFormatter format = new DataFormatter();
              for (Row row : sheet) {
                  for (int c = 0; c < row.getLastCellNum(); c++) {
                      // Null cells returned as blank
                      Cell cell = row.getCell(c, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                      String cellValue = format.formatCellValue(cell);
                      csvPrinter.print(cellValue);
                  }
                  csvPrinter.println();
              }
              csvPrinter.flush();
          }
      }
      

      进行了以下改进:

      1. 如果从未编辑过 Excel 行中的单元格,则不会引发 NullPointerException。而是将一个空白值写入 CSV。
      2. 使用 DataFormatter 呈现 Excel 值,允许 CSV 匹配 Excel 工作表的视觉表示。
      3. try-with-source 用于自动关闭文件对象。
      4. 工作簿以只读模式打开。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-16
        • 2010-10-17
        • 1970-01-01
        • 2019-02-02
        • 1970-01-01
        • 1970-01-01
        • 2014-07-10
        相关资源
        最近更新 更多