2017-09-19 186 views
1

很明顯,excel打開CSV文件很好,它應該在開始時有字節順序標記。由於數據是在請求期間生成的,所以通過在控制器中寫入HttpServletResponse的輸出流來實現CSV的下載。當我嘗試寫入BOM字節時,出現異常 - java.io.CharConversionException: Not an ISO 8859-1 character: [](即使我指定的編碼是UTF-8)。用Spring編寫的以UTF-8編碼的CSV文件,使用BOM


控制器在問題的方法

@RequestMapping("/monthly/list") 
public List<MonthlyDetailsItem> queryDetailsItems(
     MonthlyDetailsItemQuery query, 
     @RequestParam(value = "format", required = false) String format, 
     @RequestParam(value = "attachment", required = false, defaultValue="false") Boolean attachment, 
     HttpServletResponse response) throws Exception 
{ 
    // load item list 
    List<MonthlyDetailsItem> list = detailsSvc.queryMonthlyDetailsForList(query); 
    // adjust format 
    format = format != null ? format.toLowerCase() : "json"; 
    if (!Arrays.asList("json", "csv").contains(format)) format = "json"; 

    // modify common response headers 
    response.setCharacterEncoding("UTF-8"); 
    if (attachment) 
     response.setHeader("Content-Disposition", "attachment;filename=duomenys." + format); 

    // build csv 
    if ("csv".equals(format)) { 
     response.setContentType("text/csv; charset=UTF-8"); 
     response.getOutputStream().print("\ufeff"); 
     response.getOutputStream().write(buildMonthlyDetailsItemCsv(list).getBytes("UTF-8")); 
     return null; 
    } 

    return list; 
} 
+0

您可以嘗試'response.getOutputStream()。write(「\ ufeff」.getBytes(「UTF-8」));'爲BOM部分? – Berger

回答

0

它沒有多大意義:在BOM是UTF-16; UTF-8沒有字節順序。您使用setCharacterEncoding設置的編碼用於getWriter,而不是用於getOutputStream。

UPDATE:

OK,試試這個:

if ("csv".equals(format)) { 
    response.setContentType("text/csv; charset=UTF-8"); 
    PrintWriter out = response.getWriter(); 
    out.print("\uFEFF"); 
    out.print(buildMonthlyDetailsItemCsv(list)); 
    return null; 
} 

我假設buildMonthlyDetailsItemCsv返回一個字符串該方法。

+0

這是不正確的。請參閱https://en.wikipedia.org/wiki/Byte_order_mark。有一個爲UTF-8定義的BOM,但它不是強制性的。唉,Java無法自動處理UTF-8 BOM。 – vanje

+0

@vanje這對UTF-8編碼沒用。 –

+0

也許吧。但這不是重點。有時你必須處理它。沒用或沒有。 – vanje

相關問題