import React, { useState } from "react";
export default function SaveFileDemo() {
const [filename, setFilename] = useState("example.txt");
const [content, setContent] = useState("Hello, showSaveFilePicker!");
const handleSave = async () => {
try {
if ("showSaveFilePicker" in window) {
const handle = await window.showSaveFilePicker({
suggestedName: filename,
types: [
{
description: "Text Files",
accept: { "text/plain": [".txt"] },
},
],
});
const writable = await handle.createWritable();
await writable.write(new Blob([content], { type: "text/plain" }));
await writable.close();
alert("保存成功");
} else {
// fallback: trigger download
const blob = new Blob([content], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
alert("浏览器不支持 showSaveFilePicker,已触发下载");
}
} catch (err) {
console.error(err);
alert("保存被取消或出错: " + (err?.message || err));
}
};
return (
<div style={{ padding: 16, fontFamily: "Segoe UI, Arial" }}>
<h3>测试 showSaveFilePicker</h3>
<div style={{ marginBottom: 8 }}>
<label>文件名:
<input value={filename} onChange={e => setFilename(e.target.value)} />
</label>
</div>
<div style={{ marginBottom: 8 }}>
<label>内容:</label>
<br />
<textarea
rows={8}
cols={60}
value={content}
onChange={e => setContent(e.target.value)}
/>
</div>
<button onClick={handleSave}>保存文件</button>
<div style={{ marginTop: 12, color: "#555" }}>
注: Edge (Chromium) 需为最新版本且允许该 API。若不起作用,请确认浏览器版本与权限。
</div>
</div>
);
}
1371

被折叠的 条评论
为什么被折叠?



