1、pdf文件
(1)<embed src={fileUrl} type="application/pdf" width="100%" height="700" />
(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 react-file-viewer@0.5.0 --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時調用
3、excel
使用 sheetjs 插件,參考官方文檔:https://github.com/SheetJS/sheetjs
安裝:npm/cnpm install xlsx --save
(1)直接渲染出excel表,但是不太美觀
參考文章:https://jstool.gitlab.io/zh-cn/demo/sheetjs-xlsx-js/
效果如下:
(2)獲取表格數據,可自定義樣式。參考文章:https://www.cnblogs.com/yuyuan-bb/p/10965104.html
1 import XLSX from 'xlsx'; 2 import React, { useState } from 'react'; 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; // 加上breack表示只讀取第一張表 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={fileUrl}>下載</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);
效果如下: