首页 > 代码库 > 记一次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;
    }
View Code

 

【服务*** 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;
    }
View Code

 

至此结束。

 

记一次java生成csv文件乱码的解决过程 (GB2312编码)