如何用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
相关产品推荐
相关产品推荐

