docs.sheetjs.com/docz/docs/09-miscellany/02-errors.md

405 lines
13 KiB
Markdown
Raw Normal View History

2022-08-29 06:40:12 +00:00
---
sidebar_position: 2
title: Troubleshooting
hide_table_of_contents: true
---
2023-04-27 09:12:19 +00:00
import current from '/version.js';
2023-05-07 13:58:36 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-04-27 09:12:19 +00:00
2022-08-29 06:40:12 +00:00
Here are some common errors and their resolutions. This is not comprehensive.
2022-10-04 20:37:38 +00:00
The [issue tracker](https://git.sheetjs.com/SheetJS/sheetjs/issues) has a
wealth of information and user-contributed examples.
2022-08-29 06:40:12 +00:00
2022-10-19 18:48:35 +00:00
**Many of these errors have been fixed in newer releases!** Ensure that the
latest version of the library is being used. Some legacy endpoints are out of
2023-05-27 23:07:45 +00:00
date. [Review the Installation instructions.](/docs/getting-started/installation)
2022-10-19 18:48:35 +00:00
2022-08-29 06:40:12 +00:00
If issues are not covered in the docs or the issue tracker, or if a solution is
not discussed in the documentation, we would appreciate a bug report.
:::info Special Thanks
Special thanks to the early adopters and users for discovering and sharing many
workarounds and solutions!
:::
## Errors
2022-11-03 21:14:12 +00:00
#### Uncaught TypeError: Cannot read property of undefined
Errors include
```
Uncaught TypeError: Cannot read property 'read' of undefined
Uncaught TypeError: Cannot read property 'writeFile' of undefined
Uncaught TypeError: Cannot read property 'utils' of undefined
```
The root cause is an undefined `XLSX` variable. This usually means the library
was not properly loaded.
2023-05-27 23:07:45 +00:00
[Review the Installation instructions.](/docs/getting-started/installation)
2022-11-03 21:14:12 +00:00
If the error shows up while using the latest version, projects may require
other configuration or loading strategies.
<details><summary><b>Upgrade Note</b> (click to show)</summary>
Older versions of the library only shipped with CommonJS and standalone script.
Webpack and other bundlers supported CommonJS dependencies with default import:
```js
// old way
import XLSX from "xlsx";
```
Newer versions of the library ship with an ESM build. When upgrading, imports
should be updated:
```js
// new way
import * as XLSX from "xlsx";
import * as cptable from "xlsx/dist/cpexcel.full.mjs";
XLSX.set_cptable(cptable);
```
Newer releases support tree shaking, and special methods like `writeFileXLSX`
help reduce bundle size.
[The bundler note](/docs/getting-started/installation/frameworks) explains in
further detail.
</details>
2022-10-19 18:48:35 +00:00
#### "Aw Snap!" or "Oops, an error has occurred!"
Browsers have strict memory limits and large spreadsheets can exceed the limits.
2022-10-24 16:49:28 +00:00
<details><summary><b>Technical Limitations</b> (click to show)</summary>
V8 (Node/Chrome) have a maximum string length that has changed over the years.
Node 16 and Chrome 106 enforce a limit of 536870888 characters. This issue will
manifest with error messages such as `Invalid string length`.
There are memory bottlenecks associated with string addresses. A number of bugs
have been reported to the V8 and Chromium projects on this subject. While those
2022-10-31 00:58:49 +00:00
bugs are being resolved, for sheets containing hundreds of thousands of rows,
dense mode worksheets should be used.
2022-10-24 16:49:28 +00:00
</details>
2022-10-30 05:45:37 +00:00
The API functions support [dense mode](/docs/csf/sheet#dense-mode):
2022-10-24 16:49:28 +00:00
```js
var wb = XLSX.read(data, {dense: true}); // creates a dense-mode sheet
XLSX.writeFile(data, "large.xlsx"); // writeFile can handle dense-mode sheets
```
2022-10-19 18:48:35 +00:00
When processing very large files is a must, consider running processes in the
server with NodeJS or some other server-side technology.
If the files are small, please [report to our issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues)
2023-02-08 02:12:21 +00:00
#### Invalid HTML: could not find table
Data can be fetched and parsed by the library:
```js
const response = await fetch("test.xlsx");
const wb = XLSX.read(await response.arrayBuffer());
```
If the file does not exist, servers will send a 404 response that may include a
friendly HTML page. Without checking the response code, the integration will try
to read the 404 page and fail since the HTML typically has no TABLE elements.
When building a project with CRA or other templates, spreadsheets must be placed
in the `public` folder. That folder is served by the dev server and copied in
the build process.
Integration code should defend against network issues by checking status code.
For example, when using `fetch`:
```js
async function fetch_workbook_and_error_on_404(url) {
const response = await fetch(url);
if(res.status == 404) throw new Error("404 File Not Found");
const ab = await response.arrayBuffer();
return XLSX.read(ab);
}
```
2023-02-15 01:00:49 +00:00
#### Cloudflare Worker "Error: Script startup exceeded CPU time limit."
This may show up in projects with many dependencies. The official workaround is
dynamic `import`. For example:
```ts
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
// highlight-next-line
const XLSX = await import("xlsx"); // dynamic import
const wb = XLSX.read("abc\n123", {type: "string"});
const buf = XLSX.write(wb, {type: "buffer", bookType: "xlsb"});
const response = new Response(buf);
response.headers.set("Content-Disposition", 'attachment; filename="cf.xlsb"');
return response;
},
};
```
2023-04-14 08:13:40 +00:00
#### "require is not defined"
This error will be displayed in the browser console and will point to `xlsx.mjs`
Older versions of Webpack do not support `mjs` for ECMAScript Modules. This
typically affects older `create-react-app` projects.
[The "Standalone" build](/docs/getting-started/installation/standalone) should
be loaded using `require` or `import`:
_CommonJS_
```js
var XLSX = require("xlsx/dist/xlsx.full.min");
```
_ECMAScript Modules_
```js
import * as XLSX from "xlsx/dist/xlsx.full.min.js";
```
2022-08-29 06:40:12 +00:00
#### SCRIPT5022: DataCloneError
2022-08-29 20:34:30 +00:00
IE10 does not properly support `Transferable`.
2022-08-29 06:40:12 +00:00
#### Object doesn't support property or method 'slice'
IE does not implement `Uint8Array#slice`. An implementation is included in the
2022-10-30 05:45:37 +00:00
shim script. Check [the "Standalone" Installation note](/docs/getting-started/installation/standalone#internet-explorer-and-older-browsers)
2022-08-29 06:40:12 +00:00
#### TypeError: f.substr is not a function
Some Google systems use the `base64url` encoding. `base64url` and `base64` are
different encodings. A simple regular expression can translate the data:
```js
var wb = XLSX.read(b64.replace(/_/g, "/").replace(/-/g, "+"), {type:'base64'});
```
#### Error: Cannot read property '0' of undefined
`FileReader#readAsText` will corrupt binary data including XLSX, XLSB, XLS, and
other binary spreadsheet files.
Applications should use `FileReader#readAsArrayBuffer` or `Blob#arrayBuffer`.
2022-10-30 05:45:37 +00:00
Examples are included [in "User Submissions"](/docs/solutions/input#example-user-submissions)
2022-08-29 06:40:12 +00:00
Applications specifically targeting legacy browsers like IE10 should use
`FileReader#readAsBinaryString` to read the data and call `XLSX.read` using the
`binary` type.
#### `Unsupported file undefined` when reading ArrayBuffer objects
Old versions of the library did not automatically detect `ArrayBuffer` objects.
<details><summary><b>Workaround</b> (click to show)</summary>
:::warning Legacy workaround
2022-08-29 20:34:30 +00:00
This solution is not recommended for production deployments. Native support
2022-08-29 06:40:12 +00:00
for `ArrayBuffer` was added in library version `0.9.9`.
:::
After reading data with `FileReader#readAsArrayBuffer`, manually translate to
binary string and call `XLSX.read` with type `"binary"`
```js
document.getElementById('file-object').addEventListener("change", function(e) {
var files = e.target.files,file;
if (!files || files.length == 0) return;
file = files[0];
var fileReader = new FileReader();
fileReader.onload = function (e) {
var filename = file.name;
// pre-process data
var binary = "";
var bytes = new Uint8Array(e.target.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
// call 'xlsx' to read the file
var oFile = XLSX.read(binary, {type: 'binary', cellDates:true, cellStyles:true});
};
fileReader.readAsArrayBuffer(file);
});
```
</details>
2022-10-19 18:48:35 +00:00
#### Browser is stuck!
By default, operations run in the main renderer context and block the browser
2023-04-29 11:21:37 +00:00
from updating. [Web Workers](/docs/demos/bigdata/worker) offload the hard work
to separate contexts, freeing up the renderer to update.
2022-08-29 06:40:12 +00:00
2022-10-20 18:47:20 +00:00
#### Strange exported file names in the web browser
JS and the DOM API do not have a standard approach for creating files. There was
2022-11-07 10:41:00 +00:00
a `saveAs` proposal as part of "File API: Writer" but it was abandoned in 2014.
2022-10-20 18:47:20 +00:00
The library integrates a number of platform-specific techniques for different
environments. In modern web browsers, the library uses the `download` attribute.
2022-11-07 10:41:00 +00:00
Third party libraries like `FileSaver.js` provide an implementation of `saveAs`
that include more browser-specific workarounds.
2022-10-20 18:47:20 +00:00
<details><summary><b>FileSaver.js integration</b> (click to show)</summary>
_Standalone Build_
2023-05-07 13:58:36 +00:00
<CodeBlock language="html">{`\
2022-10-20 18:47:20 +00:00
<script src="https://unpkg.com/file-saver@2.0.5/dist/FileSaver.js"></script>
2023-05-07 13:58:36 +00:00
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>
<!-- XLSX.writeFile will use the FileSaver \`saveAs\` implementation -->`}
</CodeBlock>
2022-10-20 18:47:20 +00:00
_Frameworks and Bundlers_
At the time of writing, `file-saver@2.0.5` leaks `saveAs` to the global scope,
so merely importing the module works:
```js
import FileSaver from 'file-saver'; // as a side effect, `saveAs` is visible
import { writeFile } from 'xlsx'; // writeFile will use the global `saveAs`
```
</details>
2022-08-29 06:40:12 +00:00
## Data Issues
2022-10-11 04:46:01 +00:00
#### Generated XLSX files are very large!
By default, compression is disabled. Set the option `compression: true` in the
`write` or `writeFile` options object. For example:
```js
XLSX.writeFile(workbook, "export.xlsx", { compression: true });
```
2022-08-29 06:40:12 +00:00
#### CSV and XLS files with Chinese or Japanese characters look garbled
The ESM build, used in tools like Webpack and in Deno, does not include the
2022-10-30 05:45:37 +00:00
codepage tables by default. The ["Frameworks and Bundlers"](/docs/getting-started/installation/frameworks#encoding-support)
2022-08-29 06:40:12 +00:00
section explains how to load support.
2022-09-09 23:44:12 +00:00
#### DBF files with Chinese or Japanese characters have underscores
As mentioned in the previous answer, codepage tables must be loaded.
When reading legacy files that do not include character set metadata, the
`codepage` option controls the codepage. Common values:
| `codepage` | Description |
|-----------:|:-------------------------|
| 874 | Windows Thai |
| 932 | Japanese Shift-JIS |
| 936 | Simplified Chinese GBK |
| 950 | Traditional Chinese Big5 |
| 1200 | UTF-16 Little Endian |
| 1252 | Windows Latin 1 |
When writing files in legacy formats like DBF, the default codepage 1252 will
be used. The codepage option will override the setting. Any characters missing
from the character set will be replaced with underscores.
2022-08-29 06:40:12 +00:00
#### Worksheet only includes one row of data
Some third-party writer tools will not update the dimensions records in XLSX or
XLS or XLSB exports. SheetJS utility functions will skip values not in range.
The following helper function will recalculate the range:
```js
function update_sheet_range(ws) {
var range = {s:{r:Infinity, c:Infinity},e:{r:0,c:0}};
Object.keys(ws).filter(function(x) { return x.charAt(0) != "!"; }).map(XLSX.utils.decode_cell).forEach(function(x) {
range.s.c = Math.min(range.s.c, x.c); range.s.r = Math.min(range.s.r, x.r);
range.e.c = Math.max(range.e.c, x.c); range.e.r = Math.max(range.e.r, x.r);
});
ws['!ref'] = XLSX.utils.encode_range(range);
}
```
<details><summary><b>More Code Snippets</b> (click to show) </summary>
`set_sheet_range` changes a sheet's range given a general target spec that can include only the start or end cell:
```js
/* given the old range and a new range spec, produce the new range */
function change_range(old, range) {
var oldrng = XLSX.utils.decode_range(old), newrng;
if(typeof range == "string") {
if(range.charAt(0) == ":") newrng = {e:XLSX.utils.decode_cell(range.substr(1))};
else if(range.charAt(range.length - 1) == ":") newrng = {s:XLSX.utils.decode_cell(range.substr(0, range.length - 1))};
else newrng = XLSX.utils.decode_range(range);
} else newrng = range;
if(newrng.s) {
if(newrng.s.c != null) oldrng.s.c = newrng.s.c;
if(newrng.s.r != null) oldrng.s.r = newrng.s.r;
}
if(newrng.e) {
if(newrng.e.c != null) oldrng.e.c = newrng.e.c;
if(newrng.e.r != null) oldrng.e.r = newrng.e.r;
}
return XLSX.utils.encode_range(oldrng);
}
/* call change_sheet and modify worksheet */
function set_sheet_range(sheet, range) {
sheet['!ref'] = change_range(sheet['!ref'], range);
}
```
_Adding a cell to a range_
```js
function range_add_cell(range, cell) {
var rng = XLSX.utils.decode_range(range);
var c = typeof cell == 'string' ? XLSX.utils.decode_cell(cell) : cell;
if(rng.s.r > c.r) rng.s.r = c.r;
if(rng.s.c > c.c) rng.s.c = c.c;
if(rng.e.r < c.r) rng.e.r = c.r;
if(rng.e.c < c.c) rng.e.c = c.c;
return XLSX.utils.encode_range(rng);
}
range_add_cell("A1:C3","B2")
function add_to_sheet(sheet, cell) {
sheet['!ref'] = range_add_cell(sheet['!ref'], cell);
}
```
2022-12-28 11:56:52 +00:00
</details>
#### Corrupt files
Third-party build tools and frameworks may post-process SheetJS scripts. The
changes may result in corrupt files.
In the web browser, the standalone scripts from the SheetJS CDN will use proper
encodings and should work in applications. The scripts typically can be added
to an `index.html` file, bypassing any third-party post-processing
There are known bugs with the SWC minifier (used in Next.js 13+). The original
minifier can be enabled by setting `swcMinify: false` in `next.config.js`.