首页 > 代码库 > 记一次java生成csv文件乱码的解决过程 (GB2312编码)
记一次java生成csv文件乱码的解决过程 (GB2312编码)
系统:win7 (格式:中文(简体,中国))
工具:Eclipse (默认编码utf-8)
服务两个:【restful接口】 和 【服务*** server】。
场景:【服务*** server】多次调用【restful接口】,每次【restful接口】会返回一个生成好的csv文件内容。【服务*** server】将每次【restful接口】返回的csv内容保存成一个csv文件。并将生成的多个csv文件打包成一个zip压缩包。
【restful接口】:根据一组数据生成csv文件
1. java代码生成csv文件,文件输出流编码设置为"UTF-8"时,生成的csv文件打开后,中文乱码。
2. 将文件输出流编码设置为"GB2312",生成的csv文件打开后,中文没有乱码。
java代码如下:
/** * 生成.csv格式文件 */ public static boolean createCsvFile(List<Object[]> rows, String filePath, String fileName) { // 标记文件生成是否成功 boolean flag = true; // 文件输出流 BufferedWriter fileOutputStream = null; try { // 含文件名的全路径 String fullPath = filePath + File.separator + fileName + Constants.SUFFIX_CSV; File file = new File(fullPath); if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录 file.getParentFile().mkdirs(); } if (file.exists()) { // 如果已存在,删除旧文件 file.delete(); } file = new File(fullPath); file.createNewFile(); // 格式化浮点数据 NumberFormat formatter = NumberFormat.getNumberInstance(); formatter.setMaximumFractionDigits(10); // 设置最大小数位为10 // 格式化日期数据 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); // 实例化文件输出流 fileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "GB2312"), 1024); // 遍历输出每行 Iterator<Object[]> ite = rows.iterator(); while (ite.hasNext()) { Object[] rowData = (Object[]) ite.next(); for (int i = 0; i < rowData.length; i++) { Object obj = rowData[i]; // 当前字段 // 格式化数据 String field = ""; if (null != obj) { if (obj.getClass() == String.class) { // 如果是字符串 field = (String) obj; } else if (obj.getClass() == Double.class || obj.getClass() == Float.class) { // 如果是浮点型 field = formatter.format(obj); // 格式化浮点数,使浮点数不以科学计数法输出 } else if (obj.getClass() == Integer.class || obj.getClass() == Long.class || obj.getClass() == Short.class || obj.getClass() == Byte.class) { // 如果是整形 field += obj; } else if (obj.getClass() == Date.class) { // 如果是日期类型 field = sdf.format(obj); } } else { field = " "; // null时给一个空格占位 } // 拼接所有字段为一行数据 if (i < rowData.length - 1) { // 不是最后一个元素 fileOutputStream.write("\"" + field + "\"" + ","); } else { // 是最后一个元素 fileOutputStream.write("\"" + field + "\""); } } // 创建一个新行 if (ite.hasNext()) { fileOutputStream.newLine(); } } fileOutputStream.flush(); } catch (Exception e) { flag = false; log.error("生成数据文件是报错!", e); e.printStackTrace(); } finally { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return flag; }
【服务*** server】:通过restful接口来获取csv文件内容,并保存成csv文件
1. 【restful接口】通过流读取用"GB2312"编码生成的csv文件,此时数据流的编码是个仍旧是"GB2312".
2. 【服务*** server】通过【restful接口】来获取csv文件内容,因为 服务【服务*** server】的默认编码是"iso-8859-1"。此时接受到的csv内容编码由"GB2312"被强转成了"iso-8859-1". 此时,Eclipse中debug看到的csv内容中文是乱码的。
3. 【服务*** server】侧,重新编码csv内容,使汉字不再乱码。
// content是接收到的csv内容的字符串(String类型)
content = convertEncodingFormat(content, "iso-8859-1", "GB2312");
4. 【服务*** server】如果想在本地将接收到的csv文件保存起来,并且中文可见。还需要设置输出流编码设置为"GB2312"。
/** * 把内容写入文件csv,因为csv使用GB2312编码,需要单独处理 */ @SuppressWarnings("resource") public static boolean createCsvFileWithContent(String parentPath, String fileName, String contentStr) { // 标记文件生成是否成功 boolean flag = true; // 拼接文件完整路径 String fullPath = parentPath + File.separator + fileName; // 文件输出流 BufferedWriter fileOutputStream = null; // 生成json格式文件 try { // File file = new File(fullPath); if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录 file.getParentFile().mkdirs(); } if (file.exists()) { // 如果已存在,删除旧文件 file.delete(); } file = new File(fullPath); file.createNewFile(); // 实例化文件输出流 fileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "GB2312"), 1024); fileOutputStream.write(contentStr); fileOutputStream.flush(); } catch (Exception e) { flag = false; log.error("生成数据文件是报错!", e); e.printStackTrace(); } // 返回是否成功的标记 return flag; }
至此结束。
记一次java生成csv文件乱码的解决过程 (GB2312编码)