React:write 到 json 文件或 export/download [无服务器]
React:write to json file or export/download [no server]
我对 JS/TS 中的文件 I/O 感到很困惑。我看到的大多数示例都适用于 DOM 并且具有基于浏览器的解决方案。
此外,我不明白如何使 fs
工作,它似乎需要一个 webpack 配置,我使用 CRA 并且不想弹出。
在 React 组件中,我想从服务器获取一些数据,然后将它们保存为项目文件夹中的 JSON 文件(相同的路径,root,public 文件夹,无论如何)或直接下载(无需按钮)。
//data type just in case
inteface IAllData{ name:string; allData:IData[];}
所以在获取一些数据后想将它们保存到 name.json
public componentDidMount(){
this.fetchData().then(()=>this.saveData())
}
public async fetchData(){/* sets data in state*/}
public saveData(){
const {myData}=this.state;
const fileName=myData.name;
const json=JSON.stringify(myData);
const blob=new Blob([json],{type:'application/json'})
/* How to write/download this blob as a file? */
}
这里尝试 window.navigator.msSaveOrOpenBlob(blob, 'export.json');
没用
注意:我知道它有安全隐患,不适合生产。最好将文件保存在项目文件夹中,但下载完全可以。
我有一个包含数据的 blob,我在 Whosebug 上找到了一个解决方案并进行了一些操作,并成功下载为 xlsx 文件。我在下面添加我的代码,它也可能对您有所帮助。
const blob = await res.blob(); // blob just as yours
const href = await URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.download = "file.xlsx";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
编辑:我已经为你的情况编写了一个函数,你可以使用下面的函数,但要小心 "fileName"(在我的情况下不在 "this.state" 对象中)和 "myData"存储在 "this.state" object.
中的对象
const downloadFile = async () => {
const {myData} = this.state; // I am assuming that "this.state.myData"
// is an object and I wrote it to file as
// json
const fileName = "file";
const json = JSON.stringify(myData);
const blob = new Blob([json],{type:'application/json'});
const href = await URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.download = fileName + ".json";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
对于像我这样在已经将 JSON 作为变量的情况下寻找更简单解决方案的人:
<button
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
<button
type="button"
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
如果您使用的是 Loic V 方法,只需在按钮元素上添加按钮的类型,就可以正常工作。
我对 JS/TS 中的文件 I/O 感到很困惑。我看到的大多数示例都适用于 DOM 并且具有基于浏览器的解决方案。
此外,我不明白如何使 fs
工作,它似乎需要一个 webpack 配置,我使用 CRA 并且不想弹出。
在 React 组件中,我想从服务器获取一些数据,然后将它们保存为项目文件夹中的 JSON 文件(相同的路径,root,public 文件夹,无论如何)或直接下载(无需按钮)。
//data type just in case
inteface IAllData{ name:string; allData:IData[];}
所以在获取一些数据后想将它们保存到 name.json
public componentDidMount(){
this.fetchData().then(()=>this.saveData())
}
public async fetchData(){/* sets data in state*/}
public saveData(){
const {myData}=this.state;
const fileName=myData.name;
const json=JSON.stringify(myData);
const blob=new Blob([json],{type:'application/json'})
/* How to write/download this blob as a file? */
}
这里尝试 window.navigator.msSaveOrOpenBlob(blob, 'export.json');
没用
注意:我知道它有安全隐患,不适合生产。最好将文件保存在项目文件夹中,但下载完全可以。
我有一个包含数据的 blob,我在 Whosebug 上找到了一个解决方案并进行了一些操作,并成功下载为 xlsx 文件。我在下面添加我的代码,它也可能对您有所帮助。
const blob = await res.blob(); // blob just as yours
const href = await URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.download = "file.xlsx";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
编辑:我已经为你的情况编写了一个函数,你可以使用下面的函数,但要小心 "fileName"(在我的情况下不在 "this.state" 对象中)和 "myData"存储在 "this.state" object.
中的对象const downloadFile = async () => {
const {myData} = this.state; // I am assuming that "this.state.myData"
// is an object and I wrote it to file as
// json
const fileName = "file";
const json = JSON.stringify(myData);
const blob = new Blob([json],{type:'application/json'});
const href = await URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.download = fileName + ".json";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
对于像我这样在已经将 JSON 作为变量的情况下寻找更简单解决方案的人:
<button
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
<button
type="button"
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(YOURJSON)
)}`}
download="filename.json"
>
{`Download Json`}
</button>
如果您使用的是 Loic V 方法,只需在按钮元素上添加按钮的类型,就可以正常工作。