DOC
前端暂无方式预览,最好后端一个转PDF服务支持
DOCX
docx-preview,mammoth底层都是基于jszip解析DOCX, 仅仅支持DOCX!!!!
javascript
/**
* @file doc
* @author shenzhiqiang01
* @date 2023-08-03
*/
import React, {useRef, useState, useEffect} from 'react';
import * as docx from '../../../libs/docx-preview/docx-preview';
import style from './index.module.less';
import ErrStatus from './errStatus';
import {Loading} from 'acud';
import mammoth from 'mammoth';
// import {default as htmlParser} from 'react-html-parser'; // 支持react Deff
const DocRender = ({file}) => {
const ref = useRef(null);
const [loading, setLoading] = useState(true);
const [convertedText, setConvertedText] = useState('');
const [isErr, setIsErr] = useState(false);
const renderBlob = async file => {
docx.renderAsync(file, ref.current, undefined)
.then(x => {
setLoading(false);
console.log('docx: finished');
}).catch(err => {
console.log(err, 'err');
setIsErr(true);
}).finally(final => {
console.log(final, 'final');
setLoading(false);
});
};
const convertToWord = () => {
if (file) {
const reader = new FileReader();
reader.onload = event => {
const arrayBuffer = event.target.result;
const options = {
arrayBuffer: arrayBuffer
};
mammoth.convertToHtml(options)
.then(result => {
console.log(result, 'result');
setConvertedText(result.value);
setLoading(false);
})
.catch(error => {
console.error(error);
});
};
reader.readAsArrayBuffer(file);
}
};
useEffect(() => {
if (file) {
setLoading(true);
setIsErr(false);
renderBlob(file);
}
}, [file, ref]);
return (
<div className={style['doc-render']}>
{loading ? <Loading /> : ''}
{
isErr ? <ErrStatus className={style.errStatus} /> : <div id='doc' ref={ref}></div>
}
</div>
);
};
export default DocRender;
问题:在微前端中如果子应用相关库使用了jszip,如何解决jszip失效(docx的解析依赖jszip)
需要主应用去加载jszip,挂载在winnow中。
gcdn.grapecity.com.cn/showtopic-1...
解决:
在主应用中加载jszip
xml
<script src="/jszip.min.js"></script>
<!-- <script async src="https://unpkg.com/jszip@3.10.1/dist/jszip.min.js"></script> -->
react-pdf 兼容性较好
ini
/**
* @file index2
* @author shenzhiqiang01
* @date 2023-08-02
*/
import React, {useState, useMemo, useRef, useCallback} from 'react';
import {Document, Page, pdfjs} from 'react-pdf';
import styles from './index.module.less';
import {useMeasure} from 'react-use';
import {Loading} from 'acud';
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';
import {map} from 'lodash';
const EVERY_COUNT = 1; // 每次滑倒底时预加载几页
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
const PdfRender = ({file}) => {
const [ref, {width: wrapWidth}] = useMeasure();
const [numPages, setNumPages] = useState(0);// pdf总页数;
const currRef = useRef(); // backtop父元素dom信息
const onDocumentLoaded = ({numPages}) => {
setNumPages(numPages);
};
const pdfRenderer = useMemo(() => {
if (!file) {
return <Loading />;
}
return (
<div
ref={currRef}
>
<Document
file={file}
onLoadSuccess={onDocumentLoaded}
loading={<Loading size="large" />}
renderMode='canvas'
>
{
map(new Array(numPages).fill(Math.random()), ((item, index) => {
return (
<Page
key={index}
width={wrapWidth}
pageNumber={index + 1}
loading={<Loading size="large" />}
// customTextRenderer={textRenderer}
/>
);
}))
}
</Document>
</div>
);
}, [file, numPages, wrapWidth]);
return (
<div
ref={ref}
className={styles['pdf-render']}
>
{
pdfRenderer
}
</div>
);
};
export default PdfRender;
TXT
txt预览仅需要将blob流转成字符串即可。
但需要注意的是txt转字符串需要指定对应的编码格式,否则出现乱码。
可以使用jschardet来判断编码
ini
/**
* @file txt
* @author shenzhiqiang01
* @date 2023-08-03
*/
import React, {useRef, useState, useEffect} from 'react';
import {Input, Loading} from 'acud';
import style from './index.module.less';
import jschardet from 'jschardet';
const TxtRender = ({file}) => {
const [txtVal, setTxt] = useState();
const [loading, setLoading] = useState(true);
// 将Blob流转为字符串
const blobToString = async (blob, charset) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
console.log(charset, 'charset');
reader.readAsText(blob, 'KOI8-R');
});
};
const getCharset = async blob => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
let base64Str = reader.result;
let str = atob(base64Str.split(';base64,')[1]);
console.log(str, 'str');
jschardet.enableDebug();
let encoding = jschardet.detect(str, {
minimumThreshold: 0.1, detectEncodings:
['UTF-8', 'windows-1252', 'gb2312']
});
console.log(encoding, 'encoding---');
encoding = encoding.encoding;
if (encoding === 'window-1252') {
encoding = 'ANSI';
}
resolve(encoding);
};
});
};
const renderBlob = async file => {
// 使用示例
let charset1 = await getCharset(file);
console.log(charset1, 'charset1');
let charset = 'KOI8-R';
blobToString(file, charset)
.then(text => {
setTxt(text);
setLoading(false);
})
.catch(error => {
console.error('转换失败:', error);
});
console.log(file, 'response');
};
useEffect(() => {
if (file) {
setLoading(true);
renderBlob(file);
}
}, [file]);
return (
<div className={style['txt-render']}>
{loading ? <Loading /> : ''}
<Input.TextArea
value={txtVal}
autoSize
bordered={false}
allowClear={false}
style={{
color: '#151B26',
backgroundColor: '#fff',
border: 'none'
}}
/>
</div>
);
};
export default TxtRender;
DOC和DOCX区别
docx-preview 是一个用于预览 DOCX 格式的文档的库,它并不支持 DOC 文件的预览。这是因为 DOCX 和 DOC 两种文件格式有着不同的结构和编码方式。
DOCX 格式是基于 Office Open XML 格式的文档,它是以 XML 和 ZIP 压缩方式存储的,其中包含了文本、样式、图像和其他元数据等信息。docx-preview 可以解析和渲染 DOCX 文件,因为它能够理解和处理 DOCX 文件的结构。
然而,DOC 格式是一种较早期的二进制格式,它的结构和编码方式与 DOCX 格式不同。因此,docx-preview 无法直接解析和渲染 DOC 文件。
要在网页中预览 DOC 文件,您可能需要使用其他的库或服务,如 Apache POI、Aspose.Words 或者将 DOC 文件转换为 PDF 或 HTML 格式并在网页中进行展示。这些库和服务提供了将 DOC 文件转换为可预览的格式的功能,以便在网页中进行展示。具体选择和实现方式取决于您的项目需求和技术栈。