【问题标题】:Unreadable output from SuperCSV?SuperCSV 的输出不可读?
【发布时间】:2012-09-03 16:52:26
【问题描述】:

我为我的 Spring 控制器创建了一个实用程序类,用于调用以使用 SuperCSV 库 (http://supercsv.sourceforge.net/) 从一组 bean 生成 CSV

实用程序类非常基础:

public static void export2CSV(HttpServletResponse response,
        String[] header, String filePrefix, List<? extends Object> dataObjs) {
    try{
        response.setContentType("text/csv;charset=utf-8"); 
        response.setHeader("Content-Disposition","attachment; filename="+filePrefix+"_Data.csv");

        OutputStream fout= response.getOutputStream();  
        OutputStream bos = new BufferedOutputStream(fout);   
        OutputStreamWriter outputwriter = new OutputStreamWriter(bos); 

        ICsvBeanWriter writer = new CsvBeanWriter(outputwriter, CsvPreference.EXCEL_PREFERENCE);

        // the actual writing
        writer.writeHeader(header);

        for(Object anObj : dataObjs){
            writer.write(anObj, header);                                
        }
    }catch (Exception e){
        e.printStackTrace();
    }
};

关键是,我从这个操作中得到了不同的行为,我不知道为什么。当我从一个控制器(我们称之为“A”)调用它时,我得到了预期的数据输出。

当我从另一个控制器 ('B') 调用它时,我得到了一些无法被 OO Calc 打开的无法识别的二进制数据。在 Notepad++ 中打开它会产生一行不可读的乱码,我只能假设是读者试图向我展示二进制流。

控制器“A”调用(有效的那个)

@RequestMapping(value="/getFullReqData.html", method = RequestMethod.GET)
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{
    logger.info("INFO:  ******************************Received request for full Req data dump");
    String projName=  (String)session.getAttribute("currentProject");
    int projectID = ProjectService.getProjectID(projName);
    List<Requirement> allRecords = reqService.getFullDataSet(projectID);

      final String[] header = new String[] { 
              "ColumnA", 
              "ColumnB",                  
              "ColumnC",
              "ColumnD",
              "ColumnE"
              };

      CSVExporter.export2CSV(response, header, projName+"_reqs_", allRecords);


};

...这是控制器“B”调用(失败的那个):

@RequestMapping(value="/getFullTCData.html", method = RequestMethod.GET)
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{
    logger.info("INFO:  Received request for full TCD data dump");
    String projName=  (String)session.getAttribute("currentProject");
    int projectID = ProjectService.getProjectID(projName);
    List<TestCase> allRecords = testService.getFullTestCaseList(projectID);

    final String[] header = new String[] { 
            "ColumnW", 
            "ColumnX",
            "ColumnY",                
            "ColumnZ"
         };

    CSVExporter.export2CSV(response, header, projName+"_tcs_", allRecords);
}

观察:

  • 我首先调用哪个控制器无关紧要。 “A”总是有效,“B”总是产生乱码
  • 对该函数的两次调用都有一个标题列列表,这些标题列是传递给 CSVWriter 的 bean 中定义的总操作集的子集
  • 简单的异常 printStackTrace 正在检测 bean 的反射字段何时与定义不匹配(即无法找到 get() 以编程方式获取值),这表明所有列/变量匹配都成功。李>
  • 在调试器中,我已根据传递的对象数量验证了 writer.write(Object, header) 调用被命中预期的次数,并且这些对象具有预期的数据

任何建议或见解将不胜感激。我真的很困惑如何更好地隔离问题......

【问题讨论】:

    标签: java spring csv format supercsv


    【解决方案1】:

    你没有关闭作者。此外,CsvBeanWriter 会将 writer 包装在 BufferedWriter 中,因此您也可以简化 outputwriter

    public static void export2CSV(HttpServletResponse response,
            String[] header, String filePrefix, List<? extends Object> dataObjs) {
        ICsvBeanWriter writer;
        try{
            response.setContentType("text/csv;charset=utf-8"); 
            response.setHeader("Content-Disposition",
                "attachment; filename="+filePrefix+"_Data.csv");
    
            OutputStreamWriter outputwriter = 
                new OutputStreamWriter(response.getOutputStream()); 
    
            writer = new CsvBeanWriter(outputwriter, CsvPreference.EXCEL_PREFERENCE);
    
            // the actual writing
            writer.writeHeader(header);
    
            for(Object anObj : dataObjs){
                writer.write(anObj, header);                                
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                writer.close(); // closes writer and underlying stream
            } catch (Exception e){}
        }
    };
    

    Super CSV 2.0.0-beta-1 现已推出!除了添加许多其他功能(包括 Maven 支持和新的 Dozer 扩展)外,CSV 编写器现在还公开了 flush() 方法。

    【讨论】:

    • 知道了。不过,我很困惑,为什么调用该方法(无论顺序如何)从一个控制器调用中起作用,而如果问题出在被调用的方法内部,则从另一个控制器调用失败。
    • @Brent 也许数据的大小有影响?
    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2011-03-08
    相关资源
    最近更新 更多