1
- import mammoth from "mammoth" ;
2
- import { createElement , useCallback , useEffect , useState } from "react" ;
3
- import { DocumentViewerContainerProps } from "../typings/DocumentViewerProps" ;
1
+ import { parseAsync , renderDocument , WordDocument , Options } from "docx-preview" ;
2
+ import { createElement , useCallback , useEffect , useRef } from "react" ;
4
3
import { BaseControlViewer } from "./BaseViewer" ;
5
- import { DocRendererElement } from "./documentRenderer" ;
4
+ import { DocRendererElement , DocumentRendererProps , DocumentStatus } from "./documentRenderer" ;
5
+ import "./DocxViewer.scss" ;
6
6
7
- const DocxViewer : DocRendererElement = ( props : DocumentViewerContainerProps ) => {
8
- const { file } = props ;
9
- const [ docxHtml , setDocxHtml ] = useState < string | null > ( null ) ;
10
- const loadContent = useCallback ( async ( arrayBuffer : any ) => {
11
- try {
12
- mammoth
13
- . convertToHtml (
14
- { arrayBuffer : arrayBuffer } ,
15
- {
16
- includeDefaultStyleMap : true
17
- }
18
- )
19
- . then ( ( result : any ) => {
20
- if ( result ) {
21
- setDocxHtml ( result . value ) ;
22
- }
23
- } ) ;
24
- } catch ( error ) {
25
- setDocxHtml ( `<div>Error loading file : ${ error } </div>` ) ;
26
- }
27
- } , [ ] ) ;
7
+ const DOC_CONFIG : Partial < Options > = {
8
+ className : "docx-viewer-content" ,
9
+ ignoreWidth : true ,
10
+ ignoreLastRenderedPageBreak : false ,
11
+ inWrapper : false
12
+ } ;
13
+
14
+ const DocxViewer : DocRendererElement = ( props : DocumentRendererProps ) => {
15
+ const { file, setDocumentStatus } = props ;
16
+ const localRef = useRef < HTMLDivElement > ( null ) ;
17
+ const loadContent = useCallback (
18
+ async ( arrayBuffer : any ) => {
19
+ try {
20
+ parseAsync ( arrayBuffer , DOC_CONFIG )
21
+ . then ( ( wordDocument : WordDocument ) => {
22
+ if ( localRef . current ) {
23
+ // create new dummy stylecontainer to be ignored
24
+ const styleContainer = document . createElement ( "div" ) ;
25
+ renderDocument ( wordDocument , localRef . current , styleContainer , DOC_CONFIG ) . catch (
26
+ ( _error : any ) => {
27
+ setDocumentStatus ( DocumentStatus . error ) ;
28
+ }
29
+ ) ;
30
+ }
31
+ } )
32
+ . catch ( ( _error : any ) => {
33
+ setDocumentStatus ( DocumentStatus . error ) ;
34
+ } ) ;
35
+ } catch ( _error : any ) {
36
+ setDocumentStatus ( DocumentStatus . error ) ;
37
+ }
38
+ } ,
39
+ [ setDocumentStatus ]
40
+ ) ;
28
41
29
42
useEffect ( ( ) => {
30
43
const controller = new AbortController ( ) ;
@@ -41,11 +54,11 @@ const DocxViewer: DocRendererElement = (props: DocumentViewerContainerProps) =>
41
54
return ( ) => {
42
55
controller . abort ( ) ;
43
56
} ;
44
- } , [ file , file ? .status , file ? .value ?. uri ] ) ;
57
+ } , [ file , file . status , file . value ?. uri , loadContent ] ) ;
45
58
46
59
return (
47
- < BaseControlViewer { ...props } fileName = { file . value ?. name || "" } >
48
- { docxHtml && < div className = "docx-viewer-content" dangerouslySetInnerHTML = { { __html : docxHtml } } > </ div > }
60
+ < BaseControlViewer { ...props } file = { file } >
61
+ < div className = "docx-viewer-container" ref = { localRef } > </ div >
49
62
</ BaseControlViewer >
50
63
) ;
51
64
} ;
0 commit comments