【问题标题】:Java output JSON to CSV fileJava 输出 JSON 到 CSV 文件
【发布时间】:2014-08-22 14:30:38
【问题描述】:

我不太熟悉如何使用 Java 将文件输出回客户端。我正在尝试创建一个 CSV 文件以发送回客户端并在 Excel 中打开。

我为服务器端创建找到了this tool。我不确定如何使用它来返回实际文件。 Here 是我用来返回 txt 文件的代码示例,我认为我可以使用部分响应,但我不再获取文件,因为我正在创建这个 CSV,所以我不确定我能用什么。

在下面的代码中,我最大的问题是我必须使用控制器返回什么以及如何完成它?我不确定在这之间以及从 CSV 编写器到控制器之间我需要返回什么。任何帮助,将不胜感激。

到目前为止,这是我的代码:

控制器:

@RequestMapping(value = "/web/csvexport", method = RequestMethod.POST)
protected void processCSV(HttpServletRequest request, HttpServletResponse response, @RequestBody String jsonRequest)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try {
        CSVWriter csvWriter = new CSVWriter(); 
        JsonFlattener jsonFlattener = new JsonFlattener(); 
        String fileName = "StandardQuery"; 
        csvWriter.writeAsCSV(jsonFlattener.parseJson(jsonRequest), fileName); 

    } catch (Exception e) {
        System.out.println("Exception: " + e);
    }
}

CVS 编写器:

public class CSVWriter {
public void writeAsCSV(List<Map<String, String>> flatJson, String fileName) throws FileNotFoundException {
    Set<String> headers = collectHeaders(flatJson);
    String output = StringUtils.join(headers.toArray(), ",") + "\n";
    for (Map<String, String> map : flatJson) {
        output = output + getCommaSeperatedRow(headers, map) + "\n";
    }
    writeToFile(output, fileName);
}

private void writeToFile(String output, String fileName) throws FileNotFoundException {
    BufferedWriter writer = null;
    try {
        writer = new BufferedWriter(new FileWriter(fileName));
        writer.write(output);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        close(writer);
    }
}

private void close(BufferedWriter writer) {
    try {
        if (writer != null) {
            writer.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private String getCommaSeperatedRow(Set<String> headers, Map<String, String> map) {
    List<String> items = new ArrayList<String>();
    for (String header : headers) {
        String value = map.get(header) == null ? "" : map.get(header).replace(",", "");
        items.add(value);
    }
    return StringUtils.join(items.toArray(), ",");
}

private Set<String> collectHeaders(List<Map<String, String>> flatJson) {
    Set<String> headers = new TreeSet<String>();
    for (Map<String, String> map : flatJson) {
        headers.addAll(map.keySet());
    }
    return headers;
}

}

Json 扁平化器:

public class JsonFlattener {
public Map<String, String> parse(JSONObject jsonObject) {
    Map<String, String> flatJson = new HashMap<String, String>();
    flatten(jsonObject, flatJson, "");
    return flatJson;
}

public List<Map<String, String>> parse(JSONArray jsonArray) {
    List<Map<String, String>> flatJson = new ArrayList<Map<String, String>>();
    int length = jsonArray.length();
    for (int i = 0; i < length; i++) {
        JSONObject jsonObject = jsonArray.getJSONObject(i);
        Map<String, String> stringMap = parse(jsonObject);
        flatJson.add(stringMap);
    }
    return flatJson;
}

public List<Map<String, String>> parseJson(String json) throws Exception {
    List<Map<String, String>> flatJson = null;
    try {
        JSONObject jsonObject = new JSONObject(json);
        flatJson = new ArrayList<Map<String, String>>();
        flatJson.add(parse(jsonObject));
    } catch (JSONException je) {
        flatJson = handleAsArray(json);
    }
    return flatJson;
}

private List<Map<String, String>> handleAsArray(String json) throws Exception {
    List<Map<String, String>> flatJson = null;
    try {
        JSONArray jsonArray = new JSONArray(json);
        flatJson = parse(jsonArray);
    } catch (Exception e) {
        throw new Exception("Json might be malformed");
    }
    return flatJson;
}

private void flatten(JSONArray obj, Map<String, String> flatJson, String prefix) {
    int length = obj.length();
    for (int i = 0; i < length; i++) {
        if (obj.get(i).getClass() == JSONArray.class) {
            JSONArray jsonArray = (JSONArray) obj.get(i);
            if (jsonArray.length() < 1) continue;
            flatten(jsonArray, flatJson, prefix + i);
        } else if (obj.get(i).getClass() == JSONObject.class) {
            JSONObject jsonObject = (JSONObject) obj.get(i);
            flatten(jsonObject, flatJson, prefix + (i + 1));
        } else {
            String value = obj.getString(i);
            if (value != null)
                flatJson.put(prefix + (i + 1), value);
        }
    }
}

private void flatten(JSONObject obj, Map<String, String> flatJson, String prefix) {
    Iterator iterator = obj.keys();
    while (iterator.hasNext()) {
        String key = iterator.next().toString();
        if (obj.get(key).getClass() == JSONObject.class) {
            JSONObject jsonObject = (JSONObject) obj.get(key);
            flatten(jsonObject, flatJson, prefix);
        } else if (obj.get(key).getClass() == JSONArray.class) {
            JSONArray jsonArray = (JSONArray) obj.get(key);
            if (jsonArray.length() < 1) continue;
            flatten(jsonArray, flatJson, key);
        } else {
            String value = obj.getString(key);
            if (value != null && !value.equals("null"))
                flatJson.put(prefix + key, value);
        }
    }
}

}

这是我从中调用控制器的服务。我之前用它来返回一个 .txt 文件,所以我不确定它的可用性如何,但我认为如果我将文件流回它会处理它......:

getFile: function(jsonObj, fileName) { 
        var _defer = $q.defer(); 
        $http.post("/web/csvexport/", jsonObj).success(function(data, status, headers) {

            var octetStreamMime = "application/octet-stream";

            // Get the headers
            headers = headers();

            // Get the filename from the x-filename header or default to "download.bin"
            //var filename = headers["x-filename"] || "logfile.log";
            var filename = fileName; 

            // Determine the content type from the header or default to "application/octet-stream"
            var contentType = headers["content-type"] || octetStreamMime;

            if(navigator.msSaveBlob)
            {
                // Save blob is supported, so get the blob as it's contentType and call save.
                var blob = new Blob([data], { type: contentType });
                navigator.msSaveBlob(blob, filename);
                console.log("SaveBlob Success");
            }
            else
            {
                // Get the blob url creator
                var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
                if(urlCreator)
                {
                    // Try to use a download link
                    var link = document.createElement("a");
                    if("download" in link)
                    {
                        // Prepare a blob URL
                        var blob = new Blob([data], { type: contentType });
                        var url = urlCreator.createObjectURL(blob);
                        link.setAttribute("href", url);

                        // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
                        link.setAttribute("download", filename);

                        // Simulate clicking the download link
                        var event = document.createEvent('MouseEvents');
                        event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
                        link.dispatchEvent(event);

                        console.log("Download link Success");

                    } else {
                        // Prepare a blob URL
                        // Use application/octet-stream when using window.location to force download
                        var blob = new Blob([data], { type: octetStreamMime });
                        var url = urlCreator.createObjectURL(blob);
                        window.location = url;

                        console.log("window.location Success");
                    }

                } else {
                    console.log("Not supported");
                }
            }

【问题讨论】:

    标签: java json angularjs csv servlets


    【解决方案1】:

    首先,为什么不使用 CSV mime 类型而不是 html ?

    替换

     response.setContentType("text/html;charset=UTF-8");
    

    由

    response.setContentType("text/csv");
    

    你知道 Jackson, Java JSON API 处理 CSV 吗?看 https://github.com/FasterXML/jackson-dataformat-csv

    最后,在控制器中,您需要使用响应中的 printWriter 来写入 CSV。

    不要忘记,更喜欢 Stream 或 BufferedString 来处理大文件并具有更好的性能。

    【讨论】:

    • 我想我在尝试另一个示例后忘记将其更改回 csv。谢谢。而且我不熟悉杰克逊或那个 JSON API,我必须看看我是否可以使用它。我仍然不确定写回文件的代码
    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多