前端预览文件的几种方法

1、pdf文件

(1)<embed src={fileUrl} type="application/pdf" width="100%" height="700" />

fileUrl是后端传过来的文件地址

(2)PDF.js

PDF.js能将PDF文件渲染成Canvas

官网: https://mozilla.github.io/pdf.js/

2、office系列文件:excel、word、ppt

(1)<iframe src={`http://view.officeapps.live.com/op/view.aspx?src=${fileUrl}`} width='100%' height="700" frameBorder='1'></iframe>

这个文件必须是可以公共访问的,有的项目用的是内网,则无法使用该方法

(2)react-file-viewer,官网: https://www.npmjs.com/package/react-file-viewer

对于16.0版本以下的react使用0.5版本安装npm install [email protected] --save

16.0版本以上的react使用新版本安装npm install react-file-viewer --save

1 import FileViewer from 'react-file-viewer';
2 
3  <FileViewer
4         fileType="pdf"                         //pdf、xslx、docx、mp3、mp4
5         filePath={fileUrl}                     //文件路径
6         errorComponent={CustomErrorComponent}  //error时展示的组件
7         onError={this.onError}/>               //error时调用

使用后发现xslx不支持,pdf和docx需要解决跨域问题才能用....

3、excel

使用 sheetjs 插件,参考文章:https://www.cnblogs.com/yuyuan-bb/p/10965104.html 或官网:https://github.com/SheetJS/sheetjs

安装:npm install xlsx --save

(1)直接渲染出excel表,但是不太美观

参考:https://jstool.gitlab.io/zh-cn/demo/sheetjs-xlsx-js/

用react的话记得把result1.innerHTML改一下,原生JS是把表格直接渲染给id为result1的div,现改为:<div dangerouslySetInnerHTML={{ __html: `${ XLSX.utils.sheet_to_html(sheet)}` }}></div>

效果如下:

(2)获取表格数据,可自定义样式(记得把下面a标签的href改成后端传过来的fileUrl)。

 1 import XLSX from 'xlsx';
 2 import React, { useState } from 'xlsx';
 3 import { connect } from 'dva';
 4 
 5 const StudentsList = ({ dispatch, dictionary}) => {
 6  const [showSheetTitle, handleSheetTitle] = useState([]);
 7  const [showSheetData, handleSheetData] = useState([]);
 8  const [size, handleSize] = useState("150%");
 9  const importExcel = file => {
10     // 获取上传的文件对象
11     const { files } = file.target;
12     // 通过FileReader对象读取文件
13     const fileReader = new FileReader();
14     fileReader.onload = event => {
15       try {
16         const { result } = event.target;
17         // 以二进制流方式读取得到整份excel表格对象
18         const workbook = XLSX.read(result, { type: 'binary' });
19         let data = []; // 存储获取到的数据
20         // 遍历每张工作表进行读取(这里默认只读取第一张表)
21         for (const sheet in workbook.Sheets) {
22           if (workbook.Sheets.hasOwnProperty(sheet)) {
23             // 利用 sheet_to_json 方法将 excel 转成 json 数据
24             data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
25             // break; // 只读取第一张表
26           }
27         }
28         let sheetTitle = [];
29         let sheetData = [];
30         for (let i in data[0]){
31           if(typeof i == 'string'){
32             i.match('__EMPTY') ? sheetTitle.push("") : sheetTitle.push(i) ;
33           }else if(typeof i == 'number'){
34             i.toString() ?  sheetTitle.push(i) :  sheetTitle.push("");
35           }
36         }
37         data.length && data.map(item =>{
38           let sheetDataItem = [];
39           for(let i in item ){
40             if(typeof item[i] == 'string'){
41               item[i].match('__EMPTY') ? sheetDataItem.push("") : sheetDataItem.push(item[i]);
42             }else if(typeof item[i] == 'number'){
43               item[i].toString() ?  sheetDataItem.push(item[i]) :  sheetDataItem.push("");
44             }
45           }
46           sheetData.push(sheetDataItem);
47         })
48         console.log(data)
49         handleSheetTitle(sheetTitle);
50         handleSheetData(sheetData);
51       } catch (e) {
52         // 这里可以抛出文件类型错误不正确的相关提示
53         console.log('文件类型不正确');
54         return;
55       }
56     };
57     // 以二进制方式打开文件
58     fileReader.readAsBinaryString(files[0]);
59   }
60 
61 return  (
62   <>
63      <div style={{width: '100%', margin: '100px 0', position: 'relative'}}>
64         <div style={{overflow: 'auto', textAlign:'center', boxSizing: 'border-box', height: '400px', border: '2px inset #ddd'}}>
65           <div style={{ width: `${size}`,fontSize: '20px',display: 'flex', alignItems:'stretch',flexWrap: 'nowrap' }}>
66             {showSheetTitle.length ? showSheetTitle.map((titleItem, index)=>
67               <div key={index} style={{width: `${(100/showSheetTitle.length).toFixed(2)}%`,borderRight: '1px solid #ccc'}}>{titleItem}</div>
68             ) : null}
69           </div>
70           {showSheetData.length ? showSheetData.map((dataItem, dataIndex)=>
71             <div key ={dataIndex} style={{width: `${size}`, borderTop: '1px solid #ccc',display: 'flex',flexWrap: 'nowrap'}}>
72               {dataItem.length && dataItem.map((item, index)=>
73                 <div key={index} style={{width: `${(100/showSheetTitle.length).toFixed(2)}%`, borderRight: '1px solid #ccc'}}>{item}</div>
74               )}
75             </div>
76           ) : null}
77           <div style={{position: 'absolute',bottom: '40px', right: '40px'}}>
78             <div onClick={() =>handleSize('100%')} style={{width: '40px', height: '40px', lineHeight: '40px', borderRadius: '100%', background: '#fff'}}>紧凑</div>
79             <div onClick={()=>handleSize('150%')} style={{margin: '10px 0', width: '40px', height: '40px', lineHeight: '40px',borderRadius: '100%', background: '#fff'}}>默认</div>
80             <div onClick={() =>handleSize('200%')} style={{width: '40px', height: '40px',lineHeight: '40px', borderRadius: '100%', background: '#fff'}}>宽松</div>
81             <div style={{margin: '10px 0',width: '40px', height: '40px',lineHeight: '40px', borderRadius: '100%', background: '#fff'}}>
82               <a href="http://10.16.33.234:8888/service-teach/courseware/5f4771c4-507b-4018-8036-bb75f3fd9e79.xlsx">下载</a>
83             </div>
84           </div>
85         </div>
86       </div>
87     <input type='file' accept='.xlsx, .xls' onChange={(e)=>{importExcel(e)} }/>
88   </>
89 )
90 
91 }
92 
93 export default connect(({ dictionary}) => ({
94   dictionary,
95 }))(StudentsList);

  

 

猜你喜欢

转载自www.cnblogs.com/hejing-work/p/12803309.html