-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathExcelViewer.tsx
58 lines (50 loc) · 2 KB
/
ExcelViewer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { createElement, useCallback, useEffect, useState } from "react";
import { read, utils } from "xlsx";
import { BaseControlViewer } from "./BaseViewer";
import { DocRendererElement, DocumentRendererProps, DocumentStatus } from "./documentRenderer";
const ExcelViewer: DocRendererElement = (props: DocumentRendererProps) => {
const { file, setDocumentStatus } = props;
const [xlsxHtml, setXlsxHtml] = useState<string | null>(null);
const loadContent = useCallback(
async (arrayBuffer: any) => {
try {
const wb = read(arrayBuffer);
const sheet = wb.Sheets[wb.SheetNames[0]];
const html = utils.sheet_to_html(sheet);
setXlsxHtml(html);
} catch (_error) {
setDocumentStatus(DocumentStatus.error);
}
},
[setDocumentStatus]
);
useEffect(() => {
const controller = new AbortController();
const { signal } = controller;
if (file.status === "available" && file.value.uri) {
fetch(file.value.uri, { method: "GET", signal })
.then(res => res.arrayBuffer())
.then(response => {
loadContent(response);
});
}
return () => {
controller.abort();
};
}, [file, file.status, file.value?.uri, loadContent]);
return (
<BaseControlViewer {...props} file={file}>
{xlsxHtml && <div className="xlsx-viewer-content" dangerouslySetInnerHTML={{ __html: xlsxHtml }}></div>}
</BaseControlViewer>
);
};
ExcelViewer.contentTypes = [
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-excel.sheet.macroEnabled.12",
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"application/vnd.ms-excel.template.macroEnabled.12",
"application/vnd.ms-excel.addin.macroEnabled.12",
"application/octet-stream"
];
ExcelViewer.fileTypes = ["xlsx"];
export default ExcelViewer;