原因:
输出的CSV文件中没有BOM
什么是BOM?
在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
解决方案:
1、Excel通过“数据”->“来自文本文件”打开csv文件后,设置文件编码为utf-8
2、改变编码为UTF-16LE,添加\uFEFF
参照代码:
import java.io.BufferedOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; /** * 将数据导出到指定格式文件的工具类. * @author arenzhj * */ public class DataExportFileUtil{ //CSV config public static final String CSV_FILE = ".csv"; public static final String CSV_TYPE = "text/plain"; public static final String CSV_ENCODING = "UTF-16LE"; public static final String CSV_BOMENCODING = "\uFEFF"; //Excel config public static final String EXCEL_TYPE = "application/vnd.ms-excel"; public static final String EXCEL_FILE = ".xls"; public static final String EXCEL_ENCODING = "UTF-8"; //Excel Styles public static final String STYLE_HEADER = "HEADER"; public static final String STYLE_BORDER = "BORDER"; public static final String STYLE_DATECELL = "DATECELL"; public static final String STYLE_NUMBERCELL = "NUMBERCELL"; public static final String ENTER = "\r\n"; /** * 导出csv文件 * @param fileName * @param rowMapper * @param modelMaps * @param response * @throws Exception */ public static void exportDataCSVFile(String fileName, LinkedHashMap rowMapper, List<Map<String, String>> modelMaps, HttpServletResponse response) { ServletOutputStream out =null; BufferedOutputStream buff =null; try { out = response.getOutputStream(); buff = new BufferedOutputStream(out); StringBuffer write = new StringBuffer(); // 写入文件头部 for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator.hasNext();) { java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator .next(); write.append("\"" + propertyEntry.getValue().toString() + "\""); if (propertyIterator.hasNext()) { write.append(","); } } write.append(ENTER); // 写入文件内容 for (Iterator iterator = modelMaps.iterator(); iterator.hasNext();) { Map<String, String> modelMap =(Map<String, String>)iterator.next(); for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator.hasNext();) { java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next(); write.append("\"" + modelMap.get(propertyEntry.getKey()) + "\""); if (propertyIterator.hasNext()) { write.append(","); } } if (iterator.hasNext()) { write.append(ENTER); } } //输出Excel文件. response.setContentType(CSV_TYPE+";charset="+CSV_ENCODING); //中文文件名支持 String encodedfileName = new String(fileName.getBytes(CSV_ENCODING), CSV_ENCODING); response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName +CSV_FILE + "\""); buff.write((CSV_BOMENCODING+write.toString()).getBytes(CSV_ENCODING)); buff.flush(); buff.close(); } catch (IOException e) { e.printStackTrace(); }finally { try { buff.close(); out.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * 导出Excel(含多个Sheet) * @param fileName 导出Excel文件名称 * @param sheetNames 导出Excel的Sheet名 * @param rowMappers 各Excel数据标题 * @param modelMaps 各Excel数据集 * @param response * @throws Exception */ public static void exportDataExcelFile(String fileName, LinkedHashMap sheetNames, Map<String,LinkedHashMap> rowMappers, Map<String,List<Map<String, String>>> modelMaps, HttpServletResponse response)throws Exception{ HSSFWorkbook workbook = new HSSFWorkbook(); //创建所有Cell Style Map<String, HSSFCellStyle> styles = createStyles(workbook); int sheetNum=0; for (Iterator sheetNameIterator = sheetNames.entrySet().iterator(); sheetNameIterator.hasNext();) { Entry sheetNameEntry = (Entry) sheetNameIterator.next(); HSSFSheet sheet = workbook.createSheet(); workbook.setSheetName(sheetNum, sheetNameEntry.getValue().toString(),HSSFWorkbook.ENCODING_UTF_16); LinkedHashMap rowMapper =rowMappers.get(sheetNameEntry.getKey()); HSSFRow row; int rowIndex = 0; short colIndex = 0; row=sheet.createRow(rowIndex); // 写入文件头部 for (Iterator headerIterator = rowMapper.entrySet().iterator(); headerIterator.hasNext();) { Entry headerEntry = (Entry) headerIterator.next(); HSSFCell cell = row.createCell(colIndex++); cell.setEncoding(HSSFCell.ENCODING_UTF_16); cell.setCellType(HSSFCell.CELL_TYPE_STRING); cell.setCellValue(headerEntry.getValue().toString()); cell.setCellStyle(styles.get(STYLE_HEADER)); // 设置该cell浮点数的显示格式 colIndex++; } rowIndex++; // 写入内容部分 List<Map<String, String>> models=modelMaps.get(sheetNameEntry.getKey()); if(!models.isEmpty()){ for (Map<String, String> modelMap : models) { row=sheet.createRow(rowIndex); colIndex = 0; for (Iterator headerIterator = rowMapper.entrySet().iterator(); headerIterator.hasNext();) { Entry headerEntry = (Entry) headerIterator.next(); HSSFCell cell = row.createCell(colIndex++); cell.setEncoding(HSSFCell.ENCODING_UTF_16); cell.setCellType(HSSFCell.CELL_TYPE_STRING); cell.setCellValue(modelMap.get(headerEntry.getKey())); cell.setCellStyle(styles.get(STYLE_BORDER)); // 设置该cell浮点数的显示格式 colIndex++; } rowIndex++; } } sheetNum++; } //输出excel文件 responseExcel(response,workbook,fileName); } private static Map<String, HSSFCellStyle> createStyles(HSSFWorkbook wb) { Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>(); //普通字体 HSSFFont normalFont = wb.createFont(); normalFont.setFontHeightInPoints((short) 10); //加粗字体 HSSFFont boldFont = wb.createFont(); boldFont.setFontHeightInPoints((short) 10); boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //蓝色加粗字体 HSSFFont blueBoldFont = wb.createFont(); blueBoldFont.setFontHeightInPoints((short) 10); blueBoldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); blueBoldFont.setColor(HSSFColor.BLUE.index); //行标题格式 HSSFCellStyle headerStyle = wb.createCellStyle(); headerStyle.setFont(boldFont); headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette(); palette.setColorAtIndex((short)9, (byte) (0xff & 200), (byte) (0xff & 200), (byte) (0xff & 200)); headerStyle.setFillForegroundColor((short)9); headerStyle.setAlignment(headerStyle.ALIGN_CENTER); headerStyle.setVerticalAlignment(headerStyle.VERTICAL_CENTER); setBorder(headerStyle); styles.put(STYLE_HEADER, headerStyle); //border HSSFCellStyle borderCellStyle = wb.createCellStyle(); setBorder(borderCellStyle); styles.put(STYLE_BORDER, borderCellStyle); HSSFDataFormat df = wb.createDataFormat(); //日期格式 HSSFCellStyle dateCellStyle = wb.createCellStyle(); dateCellStyle.setFont(normalFont); dateCellStyle.setDataFormat(df.getFormat("yyyy-MM-dd HH:mm:ss")); setBorder(dateCellStyle); styles.put(STYLE_DATECELL, dateCellStyle); //数字格式 HSSFCellStyle numberCellStyle = wb.createCellStyle(); numberCellStyle.setFont(normalFont); numberCellStyle.setDataFormat(df.getFormat("#,##0.00")); setBorder(numberCellStyle); styles.put(STYLE_NUMBERCELL, numberCellStyle); return styles; } private static void setBorder(HSSFCellStyle style) { //设置边框 style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setRightBorderColor(HSSFColor.BLACK.index); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setLeftBorderColor(HSSFColor.BLACK.index); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setTopBorderColor(HSSFColor.BLACK.index); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBottomBorderColor(HSSFColor.BLACK.index); } public static void responseExcel(HttpServletResponse response, HSSFWorkbook workbook ,String fileName) throws Exception { //输出Excel文件. response.setContentType(EXCEL_TYPE+";charset="+EXCEL_ENCODING); //中文文件名支持 String encodedfileName = new String(fileName.getBytes(EXCEL_ENCODING), EXCEL_ENCODING); response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName +EXCEL_FILE + "\""); workbook.write(response.getOutputStream()); response.getOutputStream().flush(); } }
相关推荐
Java避免UTF-8的csv文件打开中文出现...Java避免UTF-8的csv文件打开中文出现乱码的方法是使用UTF-16LE编码格式,并在文件头部输出BOM。同时,需要考虑Excel版本的兼容性问题,以确保csv文件可以正确地被打开和读取。
描述中提到的情况是用户在尝试用Excel打开UTF-8编码的CSV文件时遇到了中文乱码。这是因为Excel默认可能不支持或识别UTF-8编码,尤其是不带BOM(Byte Order Mark)的UTF-8文件。解决这个问题的方法是将这些文件转换为...
5. **加载数据**:确认编码设置无误后,点击“加载”按钮,Excel将使用UTF-8编码解析CSV文件,此时中文字符应该能正常显示。 除了以上方法,你还可以尝试其他解决方案,例如在PLSQL Developer工具中直接设置导出时...
- 文件流操作时忘记指定编码,会导致默认编码(通常是平台默认编码,如Windows的GBK)被使用,从而出现乱码。 - 读写操作时,确保编码一致,避免在转换过程中引入乱码。 6. **工具有助于调试**: - 使用文本编辑...
但是,当使用 `utf-8` 编码写入 CSV 文件时,如果文件开头没有 BOM (Byte Order Mark) 标记,那么 Excel 在打开文件时可能会出现乱码。这是因为 Excel 默认会根据 BOM 来判断文件的编码格式。 ```python import ...
如果CSV文件的编码方式为utf-8或Unicode等,EXCEL打开时就会出现中文乱码的情况。 解决这个问题的方法是使用记事本打开CSV文件,然后点击菜单:“文件-另存为”,选择ANSI编码方式,最后保存完毕后,用EXCEL打开这...
Oracle数据库可能使用的是UTF-8或其他编码,而默认的文本编辑器或Excel可能使用不同的编码。因此,当编码不匹配时,就会出现乱码。 2. **使用记事本打开并重新保存**: 第一步是使用记事本打开CSV文件。记事本是一...
在ArcGIS 10.2.2版本中,用户可能会遇到一个常见的问题:当尝试用Microsoft Excel打开与ArcGIS相关的dbf文件时,数据可能会显示为乱码。这个问题主要涉及到字符编码的不匹配,下面我们将详细探讨这个问题的原因、...
在Excel VBA编程中,有时我们需要处理大量的数据,这时候可以借助外部数据访问对象(ADO)来读取和操作数据,比如CSV(逗号分隔值)文件。CSV格式因其通用性和简洁性,常用于数据交换。下面我们将详细介绍如何使用...
如果导出文件的编码与系统或软件默认的编码不一致,就会出现乱码现象。Vtiger 5.2.1可能默认使用了一种不支持中文的编码,导致导出的Excel和CSV文件无法正确显示中文内容。 修正这个问题通常涉及以下几个步骤: 1....
当一个UTF-8编码的CSV文件被Excel尝试以ANSI编码方式打开时,由于编码不匹配,Excel无法正确解析非ASCII字符,从而导致乱码的出现。 解决这个问题的方法是转换CSV文件的编码方式,使其与Excel的编码方式保持一致。...
然而,由于编码问题,有时在导出CSV文件时会出现乱码。本示例将详细讲解如何使用PHP正确地导出CSV文件,避免出现乱码情况,并介绍相关的关键知识点。 首先,我们需要了解字符编码的基本概念。在处理文本数据时,...
1,所有字段如在中文,一定要以汉字开头,否则不能转为utf-8编码。 2,如转换后出现乱码,请将excel表格中的内容加上边框表格。 vcf转csv转excel步骤: 导出手机vcf文件 - VCF2CSV读取vcf转为csv表格 - 打开excel\...
在导出时,需要确保文件以UTF-8编码保存。 在实际应用中,你可以通过调整Bootstrap Table的配置和插件设置,以及确保整个数据流的编码一致性,来实现中文表格数据的顺利导出。如果遇到问题,可以查阅相关插件的文档...
* 使用正确的文件编码:在保存文件时,选择正确的编码格式,例如UTF-8或GBK。 * 使用记事本打开文件:在打开文件前,使用记事本打开文件,可以避免乱码的问题。 * 使用Excel的字符集设置:在Excel中,设置正确的字符...
在使用Navicat for MySQL工具进行数据导入时,经常会出现中文乱码的问题,尤其是在处理Excel文件时更为常见。这种现象不仅影响数据的正确性,还可能导致后续的数据分析和处理出现错误。因此,有效地解决Navicat for ...
- `readCsv`方法简单地使用`Files.readFirstLine`从文件中读取第一行,同样使用UTF-8编码。 - 这个方法适用于简单的读取操作,如果需要读取整个文件,可能需要使用更复杂的方法,例如逐行迭代文件。 5. **测试...
里面有ipv4和ipv6地址,经纬度,城市,定位。GeoLite_-City_Locations-zh-CN.csv是ansi编码,可以用excel直接打开,GeoLite2-City-Locations-zh-CN.csv是utf-8编码,打开乱码。
解决方法是使用文本编辑器(如记事本)打开CSV文件,将其另存为TXT文件,确保选择正确的编码(如UTF-8),然后再用Excel打开这个新保存的TXT文件,这样通常能显示正确的汉字。 其次,如果Excel文件本身损坏导致乱码...
这里特别提到,拆分后的CSV文件不应以UTF-8格式保存,因为这可能导致中文字符出现乱码。通常,CSV文件默认采用ANSI(Windows-1252)编码,如果原始文件是用这种编码保存的,拆分后也应保持相同编码,以确保中文字符...