前提:都是通过接口获取到的文件流,然后通过以上window.URL.createObjectURL
方法将转成url传给组件

通过支持的文件类型可知word、excel、ppt类的有局限性

docx
的文件支持预览,无局限性- 应该是
xlsx
吧? 它的官网写的是xslx
,但是无法预览
这个预览docx
的效果比react-file-viewer要好
支持xlsx
、xls
、csv
此组件不能直接用于预览,而是拿到文件信息,将其转成二维数组,手动进行渲染,代码如下:
js
import React, { useEffect, useState } from 'react'
import { ExcelRenderer } from 'react-excel-renderer'
export default function ExcelViewer(file) {
const [rows, setRows] = useState([])
const [cols, setCols] = useState([])
const handleFile = (file) => {
ExcelRenderer(file, (err, resp) => {
if (err) {
console.error(err)
} else {
setCols(resp.cols)
setRows(resp.rows)
}
})
}
useEffect(() => {
if (file) {
handleFile(file.file)
}
}, [file])
return (
<div>
{rows.length > 0 && (
<div style={{ overflowX: 'auto', marginTop: '20px' }}>
<table style={{ borderCollapse: 'collapse', width: '100%' }}>
<thead>
<tr>
{cols.map((col, index) => (
<th key={index} style={{ border: '1px solid #ddd', padding: '8px' }}>
{col.name}
</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row, rowIndex) => (
<tr key={rowIndex}>
{row.map((cell, cellIndex) => (
<td key={cellIndex} style={{ border: '1px solid #ddd', padding: '8px' }}>
{cell}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
)
}
弊端:样式不空,对于合并单元格以及一些内部样式(链接、字体等)无法进行拿到其信息,也就无法渲染,只能是简单的显示内容,如下图

ppt的预览无法直接通过纯前端实现,可以采用前后端结合的方式实现,后端通过nodeJs + pptx2html,将ppt文件转成html,返回给前端进行渲染
后端示例(Node.js + pptx2html
)
js
const express = require('express');
const pptx2html = require('pptx2html');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/api/parse-pptx', upload.single('pptx'), async (req, res) => {
const result = await pptx2html(req.file.path);
res.json(result.slides);
});
前端示例
jsx
function PPTXViewer() {
const [slides, setSlides] = useState([]);
const handleUpload = async (e) => {
const file = e.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append('pptx', file);
const response = await fetch('/api/parse-pptx', {
method: 'POST',
body: formData
});
setSlides(await response.json());
};
return (
<div>
<input type="file" accept=".pptx" onChange={handleUpload} />
{slides.map((slide, index) => (
<div key={index} dangerouslySetInnerHTML={{ __html: slide.html }} />
))}
</div>
);
}
- ppt的可以换个思路:ppt转pdf,然后再预览,这样前端可以实现
总结:
pdf:支持
word:仅支持docx
excel: 支持,但是样式有问题
ppt:支持