You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Gson在Java中将JsonArray转换并返回CSV文件?

Gson JsonArray 转 CSV 文件问题解决

问题背景

需要实现函数读取Gson的JsonArray并转换为CSV文件,使用OpenCSV尝试时失败,抛出类型转换异常。

原代码

public Report buildCsv2(@NonNull Report.Type type,
                       @NonNull String ev_json_in,
                       @NonNull String titulo) throws IOException 
{;
    StringBuffer dados = repository.getJson(ev_json_in);
    var data = dados.toString();

    Gson gson = new Gson();
    JsonObject object = gson.newBuilder().create().fromJson(data, JsonObject.class);
    JsonArray array = object.getAsJsonArray(titulo);

    return Report.builder()
            .body(CsvHelper.createCsvFile(array))
            .type(type.getMediaType())
            .filename(titulo)
            .build();
}


public static Object createCsvFile(JsonArray array) {
    File file = new File("csv.csv");

    try {
        FileWriter outputfile = new FileWriter(file);
        CSVWriter writer = new CSVWriter(outputfile);
        List data = array.asList();

        writer.writeAll(data);
        writer.close();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return file.getName();
}

报错信息

<message>class com.google.gson.JsonObject cannot be cast to class [Ljava.lang.String; (com.google.gson.JsonObject is in unnamed module of loader 'app'; [Ljava.lang.String; is in module java.base of loader 'bootstrap')</message>

错误原因

  • JsonArray.asList()返回的是包含JsonObject对象的列表,而OpenCSV的CSVWriter.writeAll(List)方法要求列表元素必须是String[]类型,直接传入会触发类型强制转换失败。
  • 原代码未处理CSV表头,也未将JsonObject的键值对转换为CSV行所需的字符串数组。

解决方案

修改后代码

public Report buildCsv2(@NonNull Report.Type type,
                       @NonNull String ev_json_in,
                       @NonNull String titulo) throws IOException {
    StringBuffer dados = repository.getJson(ev_json_in);
    String data = dados.toString();

    Gson gson = new Gson();
    JsonObject object = gson.fromJson(data, JsonObject.class);
    JsonArray array = object.getAsJsonArray(titulo);

    return Report.builder()
            .body(CsvHelper.createCsvFile(array, titulo))
            .type(type.getMediaType())
            .filename(titulo)
            .build();
}

public static String createCsvFile(JsonArray array, String titulo) throws IOException {
    // 用传入的titulo作为文件名,避免重复覆盖
    File file = new File(titulo + ".csv");

    // try-with-resources自动关闭流,避免资源泄漏
    try (FileWriter outputfile = new FileWriter(file);
         CSVWriter writer = new CSVWriter(outputfile)) {

        if (array.size() == 0) {
            writer.writeNext(new String[]{});
            return file.getName();
        }

        // 从第一个JsonObject提取CSV表头
        JsonObject firstObj = array.get(0).getAsJsonObject();
        String[] header = firstObj.keySet().toArray(new String[0]);
        writer.writeNext(header);

        // 遍历JsonArray,将每个JsonObject转换为对应行的字符串数组
        List<String[]> csvRows = new ArrayList<>();
        for (JsonElement element : array) {
            JsonObject obj = element.getAsJsonObject();
            String[] row = new String[header.length];
            for (int i = 0; i < header.length; i++) {
                String key = header[i];
                // 处理缺失键的情况,转为空字符串
                row[i] = obj.has(key) ? obj.get(key).getAsString() : "";
            }
            csvRows.add(row);
        }

        writer.writeAll(csvRows);
    } catch (IOException e) {
        throw new IOException("生成CSV文件失败", e);
    }

    return file.getName();
}

关键优化点

  • 表头提取:从第一个JsonObject的键集合生成CSV表头,保证结构统一。
  • 类型匹配:将每个JsonObject的键值对按表头顺序转换为String[],符合OpenCSV的要求。
  • 资源管理:使用try-with-resources语法自动关闭文件流和CSVWriter,避免资源泄漏。
  • 容错处理:空JsonArray时写入空行,缺失键的字段转为空字符串,保证CSV格式完整。
  • 文件名优化:用传入的titulo参数命名文件,避免固定文件名导致的覆盖问题。

内容的提问来源于stack exchange,提问作者Mateus Bodanese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:50:54