You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hooks.ts 2.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import jsPreviewExcel from '@js-preview/excel';
  2. import axios from 'axios';
  3. import mammoth from 'mammoth';
  4. import { useCallback, useEffect, useRef, useState } from 'react';
  5. export const useCatchError = (api: string) => {
  6. const [error, setError] = useState('');
  7. const fetchDocument = useCallback(async () => {
  8. const ret = await axios.get(api);
  9. const { data } = ret;
  10. if (!(data instanceof ArrayBuffer) && data.retcode !== 0) {
  11. setError(data.retmsg);
  12. }
  13. return ret;
  14. }, [api]);
  15. useEffect(() => {
  16. fetchDocument();
  17. }, [fetchDocument]);
  18. return { fetchDocument, error };
  19. };
  20. export const useFetchDocument = () => {
  21. const fetchDocument = useCallback(async (api: string) => {
  22. const ret = await axios.get(api, { responseType: 'arraybuffer' });
  23. return ret;
  24. }, []);
  25. return { fetchDocument };
  26. };
  27. export const useFetchExcel = (filePath: string) => {
  28. const [status, setStatus] = useState(true);
  29. const { fetchDocument } = useFetchDocument();
  30. const containerRef = useRef<HTMLDivElement>(null);
  31. const { error } = useCatchError(filePath);
  32. const fetchDocumentAsync = useCallback(async () => {
  33. let myExcelPreviewer;
  34. if (containerRef.current) {
  35. myExcelPreviewer = jsPreviewExcel.init(containerRef.current);
  36. }
  37. const jsonFile = await fetchDocument(filePath);
  38. myExcelPreviewer
  39. ?.preview(jsonFile.data)
  40. .then(() => {
  41. console.log('succeed');
  42. setStatus(true);
  43. })
  44. .catch((e) => {
  45. console.warn('failed', e);
  46. myExcelPreviewer.destroy();
  47. setStatus(false);
  48. });
  49. }, [filePath, fetchDocument]);
  50. useEffect(() => {
  51. fetchDocumentAsync();
  52. }, [fetchDocumentAsync]);
  53. return { status, containerRef, error };
  54. };
  55. export const useFetchDocx = (filePath: string) => {
  56. const [succeed, setSucceed] = useState(true);
  57. const { fetchDocument } = useFetchDocument();
  58. const containerRef = useRef<HTMLDivElement>(null);
  59. const { error } = useCatchError(filePath);
  60. const fetchDocumentAsync = useCallback(async () => {
  61. const jsonFile = await fetchDocument(filePath);
  62. mammoth
  63. .convertToHtml(
  64. { arrayBuffer: jsonFile.data },
  65. { includeDefaultStyleMap: true },
  66. )
  67. .then((result) => {
  68. setSucceed(true);
  69. const docEl = document.createElement('div');
  70. docEl.className = 'document-container';
  71. docEl.innerHTML = result.value;
  72. const container = containerRef.current;
  73. if (container) {
  74. container.innerHTML = docEl.outerHTML;
  75. }
  76. })
  77. .catch(() => {
  78. setSucceed(false);
  79. });
  80. }, [filePath, fetchDocument]);
  81. useEffect(() => {
  82. fetchDocumentAsync();
  83. }, [fetchDocumentAsync]);
  84. return { succeed, containerRef, error };
  85. };