如何在 GWT 中将 JSONObject 转换为 .csv?
Posted
技术标签:
【中文标题】如何在 GWT 中将 JSONObject 转换为 .csv?【英文标题】:How to convert JSONObject to .csv in GWT? 【发布时间】:2019-10-07 04:55:12 【问题描述】:我对 GWT 完全陌生,如果这是一个微不足道的问题,我很抱歉,但我找不到答案。我有这个已经可以工作的功能,我可以在其中导出为 .xlsx 一个表。没关系,它正在导出文件而没有任何问题。这是使用这个第 3 方实用程序:https://github.com/stephenliberty/excel-builder.js/
我的问题我想将文件另存为 .csv 但我无法转换 JSONObject 的这个 gwt 版本( com.google.gwt.json.client.JSONObject.JSONObject()) 到 csv 中,我找不到关于这个 excel-builder-js 的任何有用的文档,如果它也可以在 csv 中导出......这怎么可能?
...
JSONObject object = new JSONObject();
object.put("head", head);
object.put("cols", columns);
object.put("data", array);
exportXlsxFromTable(JsonUtils.safeEval(object.toString()), GWT.getModuleName(), name);
...
public static native void exportXlsxFromTable(javascriptObject originalData, String project, String name) /*-
var uri = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,';
$wnd
.require(
[ project + '/excelbuilderjs/excel-builder', project + '/excelbuilderjs/Template/BasicReport' ],
function(EB, BR, downloader)
var basicReport = new BR(
name : name
);
basicReport.setHeader([
bold: false, text: name, "", ""
]);
var head = originalData['head'];
for (var i=0;i<head.length;i++)
for (var j=0;j<head[i].length;j++)
head[i][j].metadata = type: 'string' ;
basicReport.setData(head.concat(originalData['data']));
basicReport.setColumns(originalData['cols']);
var data = EB.createFile(basicReport.prepare());
// window.location.href = uri + data;
$entry(@com.mycompany.gxt.framework.view.dom.DOMUtils::downloadFile(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)("myfile.xlsx", uri, data));
);
-*/;
public static native void downloadFile(String filename, String uri, String base64) /*-
var iframeDownloadFn = function(filename, uri, base64)
var values =
fn : 'b64d',
fname : filename,
fcont : uri + base64
;
try
$wnd.document.body.removeChild($wnd.downloadIframe);
catch (e)
var iframe = $wnd.document.createElement("iframe");
$wnd.document.body.appendChild(iframe);
var iDoc = iframe.contentWindow.document;
var form = iDoc.createElement("form");
form
.setAttribute("action",
@com.mycompany.gxt.framework.client.FrameworkClient::DOWNLOAD_URL);
form.setAttribute("method", 'POST');
form.setAttribute("style", 'display: none');
for ( var property in values)
if (values.hasOwnProperty(property))
var value = values[property];
if (value instanceof Array)
for (var i = 0, l = value.length; i < l; i++)
var el = iDoc.createElement("input");
el.setAttribute("type", 'hidden');
el.setAttribute("name", property);
el.setAttribute("value", value[i]);
form.appendChild(el);
else
var el1 = iDoc.createElement("input");
el1.setAttribute("type", 'hidden');
el1.setAttribute("name", property);
el1.setAttribute("value", value);
form.appendChild(el1);
iDoc.body.appendChild(form);
form.submit();
$wnd.downloadIframe = iframe;
var clickLink = function(link, uri, base64)
var cancelled = true;
try
if (document.createEvent)
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, window, 0, 0, 0,
0, 0, false, false, false, false, 0, null);
cancelled = !link.dispatchEvent(event);
else if (link.fireEvent)
cancelled = !link.fireEvent("onclick");
catch (e)
cancelled = true;
link.parentNode.removeChild(link);
if (cancelled)
iframeDownloadFn(filename, uri, base64);
var link = $wnd.document.createElement("a");
link.setAttribute("href", uri + base64);
link.setAttribute("name", filename);
link.setAttribute("title", filename);
link.setAttribute("download", filename);
$wnd.document.body.appendChild(link);
clickLink(link, uri, base64);
-*/;
编辑:
尝试了“Mon Mohon Singha”的 javasript 建议,我现在就在这里:
JSONObject object = new JSONObject();
object.put("head", head);
object.put("cols", columns);
object.put("data", array);
exportCsvFromTable(object.toString(), GWT.getModuleName(), name);
public static native void exportCsvFromTable(String originalData, String project, String name) /*-
var uri = 'text/csv;charset=utf-8;';
function convertToCSV(jsData)
var json = jsData;
var fields = Object.keys(json[0]);
var replacer = function(key, value) return value === null ? '' : value
var csv = json.map(function(row)
return fields.map(function(fieldName)
return JSON.stringify(row[fieldName], replacer)
).join(',')
)
csv.unshift(fields.join(',')) // add header column
return csv.join('\r\n');
var data = convertToCSV(originalData);
// window.location.href = uri + data;
$entry(@com.mycompany.gxt.framework.view.dom.DOMUtils::downloadFile(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)("export.csv", uri, data));
-*/;
但是我收到了这个错误,所以我认为我没有使用正确的类型...
com.google.gwt.logging.client.LogConfiguration
SEVERE: Exception caught: Exception caught: (TypeError) : json_0_g$.map is not a function com.google.gwt.event.shared.UmbrellaException: Exception caught: Exception caught: (TypeError) : json_0_g$.map is not a function
at Unknown.fillInStackTrace_0_g$(as-0.js@3:130944)
at Unknown.Throwable_3_g$(as-0.js@8:130899)
at Unknown.Exception_3_g$(as-0.js@18:131042)
at Unknown.RuntimeException_3_g$(as-0.js@18:287158)
at Unknown.UmbrellaException_3_g$(as-0.js@25:313985)
EDIT2.:
这是注销的 JavaScriptObject。删除了一些“数据”行以更清晰:
Object
cols: Array(10)
0: name: "ID", type: "string"
1: name: "NAME", type: "string"
2: name: "FIRST NAME", type: "string"
3: name: "BIRTHDAY", type: "string"
4: name: "BIRTH PLACE", type: "string"
5: name: "BIRTH COUNTRY", type: "string"
6: name: "NATIONALITY", type: "string"
7: name: "ORGANISATION", type: "string"
8: name: "FUNCTION", type: "string"
9: name: "PLACE", type: "string"
length: 10
__proto__: Array(0)
data: Array(100)
0: (10) [1470, "John", "Doe", "03.03.1988", "", "", "CANADA", "BPA", "", ""]
1: (10) [1469, "Test", "NAme", "25.03.1999", "CANADA", "CANADA", "CANADA", "test", "", "LA"]
2: (10) [1467, "Mike", "Test2", "06.05.2019", "Paris", "", "", "test", "ikol", "LA"]
3: (10) [1465, "Flanders", "Ned2", "23.12.1974", "Salt Lake City", "", "", "Orgatest", "BPA", ""]
4: (10) [1462, "Bro", "Jo", "03.07.2018", "abc", "USA", "USA", "MY COMPANY", "Catering", "A"]
5: (10) [1461, "Bro", "Jo", "01.08.2018", "abc", "USA", "USA", "MY COMPANY", "Catering", "A"]
...
length: 100
__proto__: Array(0)
head: Array(1)
0: (10) ["ID", "NAME", "FIRST NAME", "BIRTHDAY", "BIRTH PLACE", "BIRTH COUNTRY", "NATIONALITY", "ORGANISATION", "FUNCTION", "PLACE"]
length: 1
__proto__: Array(0)
__proto__: Object
EDIT3.:
正如 Rob Newton 建议的那样,我编辑了这样的转换函数:
public static native void exportCsvFromTable(JavaScriptObject originalData, String project, String name) /*-
var uri = 'text/csv;charset=utf-8;';
function convertToCSV(jsData)
//console.log(originalData);
var json = jsData;
//var fields = Object.keys(json);
//var replacer = function(key, value) return value === null ? '' : value
var headerCSV = json.head[0].join(',');
var rowsCSV = json.data.map( function(row)
return row.join(',');
);
rowsCSV.unshift(headerCSV);
console.log(rowsCSV.join('\r\n'));
return rowsCSV.join('\r\n');
var data = convertToCSV(originalData);
// window.location.href = uri + data;
$entry(@com.mycompany.gxt.framework.view.dom.DOMUtils::downloadFile(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)("export.csv", uri, data));
-*/;
转换后的数据看起来不错:
ID,NAME,FIRST NAME,BIRTHDAY,BIRTH PLACE,BIRTH COUNTRY,NATIONALITY,ORGANISATION,FUNCTION,PLACE
31471,Test,Test,07.05.2019,New,,,XYZ,ikl,
31470,John,Doe,03.03.1988,,,Canada,XYZ,,
31469,New,Test,25.03.1999,Right,USA,USA,,LA
...
遗憾的是,下载会产生一个无效的 0bytes 文件:(
【问题讨论】:
您将包含 JSON 文本的字符串传递给 exportCsvFromTable() 和 convertToCSV()。该函数需要一个 javascript 对象。 如果我知道什么是head
cols
,data
,我可以帮助你,显示该 json 对象中的一小部分数据样本以及预期的结果将有很大帮助.
是的,我自己也在尝试以某种方式将其注销,但我不知道如何在这个 GWT 中做到这一点...... :(
添加了注销的 JavaScriptObject!
CSV 文件应该如何查找该数据?
【参考方案1】:
json 数据到 js 中的 csv
不知道 GWT。可能对你有帮助
function convertToCSV(jsData)
var json = jsData;
var fields = Object.keys(json[0]);
var replacer = function(key, value) return value === null ? '' : value
var csv = json.map(function(row)
return fields.map(function(fieldName)
return JSON.stringify(row[fieldName], replacer)
).join(',')
)
csv.unshift(fields.join(',')) // add header column
return csv.join('\r\n');
function exportCSVFile(items, fileTitle)
var csv = convertToCSV(items);
var exportedFilenmae = fileTitle + '.csv' || 'export.csv';
var blob = new Blob([csv], type: 'text/csv;charset=utf-8;' );
if (navigator.msSaveBlob)
navigator.msSaveBlob(blob, exportedFilenmae);
else
var link = document.createElement("a");
if (link.download !== undefined)
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", exportedFilenmae);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
return true
【讨论】:
谢谢,我想我已经在网站上找到了这个功能,我的问题是与 GWT 的集成 :( 好吧,我试过了,我在 Javascript 控制台中看到以下错误:严重:异常捕获:异常捕获:(TypeError):json_0_g$.map 不是函数 com.google.gwt.event .shared.UmbrellaException:捕获异常:捕获异常:(TypeError):json_0_g$.map 不是函数【参考方案2】:您需要将 JavaScriptObject 传递给转换器函数,而不是包含 JSON 的字符串。尝试对您的代码进行以下更改:
exportCsvFromTable(object.getJavaScriptObject(), GWT.getModuleName(), name);
public static native void exportCsvFromTable(JavaScriptObject originalData, String project, String name) /*-
您表明您的对象有一个名为 head
的属性,它是一个长度为 1 的数组,而 head[0] 是一个标题行列名的数组。因此,以下内容将为您提供标题行字符串:
var headerCSV = json.head[0].join(',');
实际的数据行位于名为data
的属性中,该属性是一个数组,数组中的每一项都是行中值的数组。
var rowsCSV = json.data.map( function(row)
return row.join(',');
);
现在加入标题和行,例如:
rowsCSV.unshift(headerCSV) // add header column
return rowsCSV.join('\r\n');
【讨论】:
试过了,这是我在浏览器控制台中看到的: 原因:com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot convert undefined or null to object at Unknown.keys (Unknown@-1) 在 Unknown.convertToCSV_0_g$(as-0.js@30:238179) 试过了,现在我明白了: 原因:com.google.gwt.core.client.JavaScriptException: (TypeError) : json_0_g$.map 不是 Unknown.convertToCSV_0_g$(zs- 0.js@30:238185) 在 Unknown.exportCsvFromTable_1_g$(as- 我现在就添加注销的javascript对象 注销的JavaScriptObject对我来说很奇怪...你认为synthax没问题,可以用这个函数解析吗?我看到它也使用 和 []... @VORIAND 不,我认为现有代码不会解析该对象以提供典型的 CSV 格式。参考我的更新。以上是关于如何在 GWT 中将 JSONObject 转换为 .csv?的主要内容,如果未能解决你的问题,请参考以下文章
如何在android中将jsonstring转换为jsonobject?
org.json.JSONArray 类型的无法转换为 JSONObject