Skip to main content

本地存储 API

存储 API 包含 localStoragesessionStorage,描述了仅支持字符串值和键的简单键值存储。

¥The Storage API, encompassing localStorage and sessionStorage, describes simple key-value stores that only support string values and keys.

该演示涵盖两种常见的使用模式:

¥This demo covers two common use patterns:

  • "行对象" 显示了加载和存储行对象的简单约定

    ¥"Row Objects" shows a simple convention for loading and storing row objects

  • "简单字符串" 讨论如何持久化和恢复原始存储

    ¥"Simple Strings" discusses how to persist and recover a raw Storage

测试部署

每个浏览器演示都在以下环境中进行了测试:

¥Each browser demo was tested in the following environments:

浏览器日期
Chrome 1312024-12-23
Safari 18.22024-12-31

行对象

¥Row Objects

考虑以下数据对象数组:

¥Consider the following array of objects of data:

[
{ Name: "Barack Obama", Index: 44 },
{ Name: "Donald Trump", Index: 45 },
{ Name: "Joseph Biden", Index: 46 }
]

存储 API 期望值是字符串。最简单的方法是使用 JSON.stringify 生成字符串并使用行索引作为键进行存储:

¥Storage API expects values to be strings. The simplest approach is to generate strings using JSON.stringify and store using the row index as a key:

0{"Name":"Barack Obama","Index":44}
1{"Name":"Donald Trump","Index":45}
2{"Name":"Joseph Biden","Index":46}

导入数据

¥Importing Data

从工作表开始,SheetJS sheet_to_json 方法 [^1] 生成行对象数组。localStorage.setItem 将数据存储在本地存储中:

¥Starting from a worksheet, the SheetJS sheet_to_json method[^1] generates an array of row objects. localStorage.setItem will store data in Local Storage:

function sheet_to_localStorage(worksheet) {
const aoo = XLSX.utils.sheet_to_json(worksheet);
for(let i = 0; i < aoo.length; ++i) {
localStorage.setItem(i, JSON.stringify(aoo[i]));
}
}

导出数据

¥Exporting Data

localStorage.length 返回条目总数。一个简单的 for 循环可以覆盖键(从 0localStorage.length - 1 的整数)

¥localStorage.length returns the total number of entries. A simple for loop can cover the keys (integers from 0 to localStorage.length - 1 inclusive)

localStorage.getItem 将从本地存储加载字符串化数据。

¥localStorage.getItem will load the stringified data from the Local Storage.

以下函数将数据从 localStorage 收集到字符串数组中:

¥The following function collects data from localStorage to an array of strings:

function localStorage_to_array_of_strings() {
const strings = [];
for(let i = 0; i < localStorage.length; ++i) {
aoo.push(localStorage.getItem(i));
}
return strings;
}

由于每个条目都是使用 JSON.stringify 创建的字符串,因此可以使用 JSON.parse 构造对象:

¥Since each entry is a string created using JSON.stringify, an object can be constructed using JSON.parse:

function localStorage_to_array_of_objects() {
const objects = [];
for(let i = 0; i < localStorage.length; ++i) {
aoo.push(JSON.parse(localStorage.getItem(i)));
}
return objects;
}

SheetJS json_to_sheet[^2] 方法将从对象数组中创建一个新的工作表:

¥The SheetJS json_to_sheet[^2] method will create a new worksheet from the array of objects:

function localStorage_to_sheet() {
const aoo = [];
for(let i = 0; i < localStorage.length; ++i) {
aoo.push(JSON.parse(localStorage.getItem(i)));
}
return XLSX.utils.json_to_sheet(aoo);
}

在线演示

¥Live Demo

该演示将获取 https://xlsx.nodejs.cn/pres.numbers,用行填充 localStorage,然后从行生成工作表并写入新文件。

¥This demo will fetch https://xlsx.nodejs.cn/pres.numbers, fill localStorage with rows, then generate a worksheet from the rows and write to a new file.

保存导出的文件后,可以在开发者工具的 "应用" 选项卡的 "本地存储" 部分检查本地存储:

¥After saving the exported file, the Local Storage can be inspected in the "Local Storage" section of the "Application" Tab of Developer Tools:

Local Storage view in Developer Tools

此示例用于说明目的。如果对象数组可用,强烈建议直接将该数组转换为工作表。

¥This example is for illustration purposes. If array of objects is available, it is strongly recommended to convert that array to a worksheet directly.

Live Demo (click to show)
Result
Loading...
Live Editor
function SheetJStorage() {
  const [url, setUrl] = React.useState("https://xlsx.nodejs.cn/pres.numbers");
  const set_url = (evt) => setUrl(evt.target.value);
  const [out, setOut] = React.useState("");
  const xport = React.useCallback(async() => {
    // get first worksheet data as array of objects
    const wb = XLSX.read(await (await fetch(url)).arrayBuffer());
    const aoo = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);

    // reset and populate localStorage
    localStorage.clear();
    for(var i = 0; i < aoo.length; ++i) localStorage.setItem(i, JSON.stringify(aoo[i]));

    // create new array of objects from localStorage
    const new_aoo = [];
    for(var i = 0; i < localStorage.length; ++i) {
      const row = JSON.parse(localStorage.getItem(i));
      new_aoo.push(row);
    }

    setOut(`Number of rows in LocalStorage: ${localStorage.length}`);

    // create and export workbook
    const new_ws = XLSX.utils.json_to_sheet(new_aoo);
    const new_wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(new_wb, new_ws, "Sheet1");
    XLSX.writeFile(new_wb, "SheetJStorage.xlsx");
  });

  return ( <>
    {out && ( <><a href={url}>{url}</a><pre>{out}</pre></> )}
    <b>URL: </b><input type="text" value={url} onChange={set_url} size="50"/>
    <br/><button onClick={xport}><b>Fetch!</b></button>
  </> );
}

简单字符串

¥Simple Strings

当尝试存储或恢复行对象数组时,强烈建议使用 "行对象" 方法

¥The "Row Objects" approach is strongly recommended when trying to store or recover arrays of row objects.

当目标是保存现有存储时,一般表示形式是对数组。考虑本地存储中的以下数据:

¥When the goal is to save an existing Storage, the general representation is an array of pairs. Consider the following data in Local Storage:

"b""逻辑性"
"n""数字"
"s""文本"

自然的表示是数组的数组:

¥The natural representation is an array of arrays:

[
[ "b", "Logical" ],
[ "n", "Numeric" ],
[ "s", "Textual" ]
]

导出存储

¥Exporting Storage

Web 存储迭代顺序未定义。通过使用索引作为键,行对象方法具有排序。这不适用于一般情况。

¥Web Storage iteration order is not defined. By using indices as keys, the row objects approach has an ordering. That does not apply to the general case.

在现代浏览器中,Object.entries 将生成一系列键/值对。SheetJS aoa_to_sheet[^3] 方法将该数组解释为具有 2 列(键和值)的工作表:

¥In modern browsers, Object.entries will generate an array of key/value pairs. The SheetJS aoa_to_sheet[^3] method will interpret that array as a worksheet with 2 columns (key and value):

function localStorage_to_ws() {
const aoa = Object.entries(localStorage);
return XLSX.utils.aoa_to_sheet(aoa);
}

导入存储

¥Importing Storage

另一方面,假设工作表将键存储在 A 列中,将值存储在 B 列中。带有选项 header: 1 的 SheetJS sheet_to_json[^1] 方法将生成可分配给存储的键/值对:

¥In the other direction, the worksheet is assumed to store keys in column A and values in column B. The SheetJS sheet_to_json[^1] method, with the option header: 1, will generate key/value pairs that can be assigned to a storage:

function ws_to_localStorage(ws) {
const aoa = XLSX.utils.sheet_to_json(ws, { header: 1 });
aoa.forEach(([key, val]) => localStorage.setItem(key, val));
}

在线演示

¥Live Demo

此示例使用 10 个随机键和 10 个随机值填充 localStorage,根据数据生成工作表并写入新文件。

¥This example fills localStorage with 10 random keys and 10 random values, generates a worksheet from the data and writes to a new file.

Live Demo (click to show)
Result
Loading...
Live Editor
function SheetJSRandomStorage() {
  const [out, setOut] = React.useState("");
  const [rows, setRows] = React.useState([]);
  const xport = React.useCallback(async() => {
    // reset and populate localStorage
    localStorage.clear();
    var data = [];
    for(let i = 0, last = 0; i < 10; ++i) {
      var k = ((Math.random() * 20)|0) + last;
      var v = (Math.random() * 16777216).toString(36);
      localStorage.setItem(k, v);
      data.push([k,v]);
      last = k;
    }
    setRows(Object.entries(localStorage));

    // create new worksheet from localStorage
    const aoa = Object.entries(localStorage);
    const new_ws = XLSX.utils.aoa_to_sheet(aoa);

    // create and export workbook
    const new_wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(new_wb, new_ws, "Sheet1");
    XLSX.writeFile(new_wb, "SheetJSRandomStorage.xlsx");
  });
  return ( <>
    {out && ( <><a href={url}>{url}</a><pre>{out}</pre></> )}
    {rows.length && (<table><tr><th>Key</th><th>Value</th></tr>
      {rows.map(([k,v]) => (<tr><td>{k}</td><td>{v}</td></tr>))}
    </table>) || null}
    <br/><button onClick={xport}><b>Export!</b></button>
  </> );
}

[^1]: 见 sheet_to_json 于 "实用工具"

¥See sheet_to_json in "Utilities"

[^2]: 见 json_to_sheet 于 "实用工具"

¥See json_to_sheet in "Utilities"

[^3]: 见 aoa_to_sheet 于 "实用工具"

¥See aoa_to_sheet in "Utilities"