Commit 6db57b86 authored by 田翔's avatar 田翔

fix: excel表格预览优化

parent b88c4a58
{
"name": "panda-xform",
"version": "5.1.8",
"description": "5.1.8 自动计算参数属性修改",
"version": "5.1.9",
"description": "5.1.9 excel表格预览优化",
"keywords": [
"panda-xform"
],
......@@ -45,6 +45,7 @@
"react-svg": "15.1.9",
"viewerjs": "^1.11.3",
"viewerjs-react": "^1.0.2",
"xlsx": "^0.18.5",
"yarn": "^1.22.17"
},
"devDependencies": {
......@@ -53,9 +54,9 @@
"@babel/plugin-syntax-jsx": "^7.12.13",
"@babel/plugin-transform-modules-amd": "^7.14.5",
"@umijs/fabric": "^2.0.7",
"@wisdom-map/amap": "1.1.0-beta.56",
"@wisdom-map/arcgismap": "1.4.0-178",
"@wisdom-map/basemap": "1.1.0-27",
"@wisdom-map/amap": "1.1.0-beta.42",
"@wisdom-map/arcgismap": "1.4.0-92",
"@wisdom-map/basemap": "1.1.0-18",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"check-prettier": "^1.0.3",
......@@ -131,4 +132,4 @@
"publishConfig": {
"registry": "https://g.civnet.cn:4873"
}
}
\ No newline at end of file
}
......@@ -201,6 +201,10 @@ export function downloadFile(str) {
return request({
url: `${url}/DownloadFiles?filePath=${str}`,
method: 'get',
headers: {
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
},
responseType: 'blob'
});
}
......
import React, { useMemo, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import styles from './index.less'
import { Button, Upload, message } from 'antd'
import { getFileType } from '../../../../../../constant'
......@@ -13,6 +13,7 @@ import {
import FileViewer from 'react-file-viewer'
import Viewer from 'viewerjs-react'
import Drag from '../../../../../components/Drag'
import { convertUrlToBase64 } from '../../../../../../utils/index'
const FileView = (props) => {
......@@ -22,6 +23,7 @@ const FileView = (props) => {
const [visible, setVisible] = useState(false)
const [viewVisible, setViewVisible] = useState(false)
const [showFile, setShowFile] = useState({ fileType: '', filePath: '' })
const [fileListSrc, setFileListSrc] = useState(fileList)
const icon = useMemo(() => {
if (fileType === '音频') {
......@@ -33,6 +35,20 @@ const FileView = (props) => {
return <FileZipOutlined />
}, [fileType])
useEffect(() => {
getfileListSrc()
}, [])
const getfileListSrc = async () => {
let array = []
for (let i = 0; i < fileList.length; i++) {
let src = `${window.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles?filePath=${fileList[i]}`
let value = fileList[i].includes('svg') ? await convertUrlToBase64(src) : src
array.push(value)
}
setFileListSrc(array)
}
const showList = useMemo(() => {
let list = []
fileList.forEach((item, index) => {
......@@ -50,7 +66,6 @@ const FileView = (props) => {
"response": { "code": 0, "msg": "Ok", "data": item, "stackTrace": null },
"xhr": {},
};
// if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}${site ? `&_site=${site}` : ''}`;
list.push(_obj)
}
})
......@@ -61,18 +76,14 @@ const FileView = (props) => {
if (fileType === '图片') {
return (
<div className={styles.fileView}>
<Viewer>
<div className={styles.fileView} id='panda-xform-fileView'>
<Viewer container='#app'>
{
fileList.map((v, i) => {
fileListSrc.map((v, i) => {
return (
<span className={styles.imgSpan} key={v} style={{ display: i == 0 ? 'inline-block' : 'none' }}>
<span className={styles.imgSpan} key={i} style={{ display: i == 0 ? 'inline-block' : 'none' }}>
{fileList.length !== 1 ? <span className={styles.imgSub}>{fileList.length}</span> : null}
<img
className={styles.img}
src={`${window.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles?filePath=${v}`}
>
</img>
<img className={styles.img} src={v}></img>
</span>
)
})
......@@ -96,7 +107,6 @@ const FileView = (props) => {
const option = {
name: 'file',
// action: `${window.location.origin}${uploadFileUrl}`,
listType: 'picture',
withCredentials: true,
showUploadList: download ?
......@@ -116,7 +126,7 @@ const FileView = (props) => {
}
return (
<div className={styles.fileView}>
<div className={styles.fileView} >
<Button
size='small'
icon={icon}
......
import React, { useEffect, useState } from 'react'
import styles from './index.less'
import { Upload, Button, message } from 'antd'
import { Upload, Button, message, Tabs } from 'antd'
import { UploadOutlined, FileOutlined } from '@ant-design/icons'
import FileViewer from 'react-file-viewer'
import { uploadFileUrl, downloadFileUrl } from '../../../../apis/process'
import { uploadFileUrl, downloadFileUrl, downloadFile } from '../../../../apis/process'
import { filenameVerification } from '../../../../utils'
import Drag from '../../../components/Drag'
import * as XLSX from 'xlsx'
import { convertUrlToBase64 } from '../../../../utils/index'
const accepts = {
'全部': ['.bmp', '.gif', '.jpeg', 'tiff', '.png', '.svg', '.jpg', '.docx', '.xlsx', '.pdf', '.mp4', '.mp3'],
......@@ -64,10 +66,10 @@ const FileUpload = (props) => {
const [showList, setShowList] = useState([])
const [visible, setVisible] = useState(false)
const [showFile, setShowFile] = useState({ fileType: '', filePath: '' })
const [imgVisible, setImgVisible] = useState(false)
const [workbook, setWorkbook] = useState({ SheetNames: [] })
const showType = fileType === '图片' ? 'picture-card' : 'picture'
const option = {
name: 'file',
action: `${window.location.origin}${uploadFileUrl}`,
......@@ -112,16 +114,31 @@ const FileUpload = (props) => {
if (Array.isArray(fileList)) {
setShowList(fileList)
} else {
setShowList()
setShowList([])
}
if (file.status === 'done') {
onChange(fileList.map(v => v.sourcePath).join(','))
}
},
onPreview: (file) => {
onPreview: async (file) => {
if (!preview) return message.info('该附件禁止预览')
let fileType = getFileType(file.name)
if (fileType) {
if (fileType === 'xlsx') {
downloadFile(file.sourcePath)
.then(response => response.arrayBuffer())
.then(buffer => {
const data = new Uint8Array(buffer);
const workbook = XLSX.read(data, { type: 'array' });
setWorkbook(workbook)
workbook?.SheetNames?.forEach(sheetName => {
const worksheet = workbook.Sheets[sheetName];
// 将工作表转换为 JSON 对象
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' });
console.log(sheetName, jsonData)
})
})
}
setShowFile({ name: file.name, fileType: fileType, filePath: file.url })
setVisible(true)
} else {
......@@ -130,6 +147,77 @@ const FileUpload = (props) => {
}
}
const elemet = () => {
if (['jpg', 'png', 'svg', 'jpeg'].includes(showFile.fileType)) {
return (
<div style={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<img style={{ maxWidth: '100%', maxHeight: '100%' }} src={window.location.origin + showFile.filePath}></img>
</div>
)
} else if (['xlsx'.includes(showFile.fileType)]) {
return (
<div>
<Tabs>
{
workbook?.SheetNames?.map(sheetName => {
const worksheet = workbook.Sheets[sheetName]
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' })
return (
<Tabs.TabPane tab={sheetName} key={sheetName}>
<div style={{ width: '100%', height: '550px', overflow: 'auto' }}>
<table
cellPadding={10}
style={{ width: '100%', height: '100%', display: 'block', tableLayout: 'fixed' }}
>
{
jsonData.map((row, rowIndex) => {
let maxLength = 0
jsonData.forEach((v, i) => {
if (v.length > maxLength) {
maxLength = v.length
}
})
let width = (100 / maxLength) + '%'
return (
<tbody>
<tr>
{
row.map((col, colIndex) => {
return (
<td
colSpan={row.length === 1 ? maxLength : 1}
style={{ border: '1px solid #aaa', width: width }}
>
{row[colIndex]}
</td>
)
})
}
</tr>
</tbody>
)
})
}
</table>
</div>
</Tabs.TabPane>
)
})
}
</Tabs>
</div>
)
}
return (
<FileViewer
className='fileViewer'
title='123'
fileType={showFile.fileType}
filePath={window.location.origin + showFile.filePath}
/>
)
}
const iconRender = (file, listType) => {
if (listType !== 'text') {
let fileType = getFileType(file.name)
......@@ -142,37 +230,37 @@ const FileUpload = (props) => {
return <FileOutlined />
}
const valueToList = (presetValue) => {
const valueToList = async (presetValue) => {
let fileList = []
if (presetValue) {
let list = presetValue ? presetValue.split(',') : []
list.forEach((item, index) => {
if (item) { // @Tips: 直接过滤掉名字中有异常字符的文件
let uid = index + '_' + Math.random()
for (let i = 0; i < list.length; i++) {
if (list[i]) { // @Tips: 直接过滤掉名字中有异常字符的文件
let uid = i + '_' + Math.random()
let _obj = {
uid: uid,
value: item,
name: item.split('\\').reverse()[0],
value: list[i],
name: list[i].split('\\').reverse()[0],
type: fileType === '图片' ? 'image/jpeg' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}${site ? `&_site=${site}` : ''}`,
sourcePath: item.url,
url: `${downloadFileUrl}?filePath=${list[i]}${site ? `&_site=${site}` : ''}`,
sourcePath: list[i],
thumbUrl: list[i].includes('svg') ? await convertUrlToBase64(`${window.origin}${downloadFileUrl}?filePath=${list[i]}${site ? `&_site=${site}` : ''}`) : list[i],
originFileObj: { "uid": uid },
"response": { "code": 0, "msg": "Ok", "data": item, "stackTrace": null },
"response": { "code": 0, "msg": "Ok", "data": list[i], "stackTrace": null },
"xhr": {},
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}${site ? `&_site=${site}` : ''}`;
fileList.push(_obj);
}
})
}
}
return fileList
}
useEffect(() => {
useEffect(async () => {
if (presetValue && !presetValue.includes('拍照相册')) {
addons?.setValue(addons?.dataPath, presetValue || '')
setShowList(valueToList(presetValue))
setShowList(await valueToList(presetValue))
} else {
addons?.setValue(addons?.dataPath, '')
}
......@@ -201,20 +289,7 @@ const FileUpload = (props) => {
onCancel={() => setVisible(false)}
bodyStyle={{ height: 650, overflowY: showFile.fileType.includes('xlsx') ? 'none' : "auto" }}
>
{
['jpg', 'png', 'svg', 'jpeg'].includes(showFile.fileType) ? (
<div style={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<img style={{ maxWidth: '100%', maxHeight: '100%' }} src={window.location.origin + showFile.filePath}></img>
</div>
) : (
<FileViewer
className='fileViewer'
title='123'
fileType={showFile.fileType}
filePath={window.location.origin + showFile.filePath}
/>
)
}
{elemet()}
</Drag>
</div>
)
......
......@@ -34,6 +34,20 @@ export function filenameVerification(file, special) {
};
}
export const convertUrlToBase64 = async (url) => {
const response = await fetch(url)
const blob = await response.blob()
return await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => {
const base64 = reader.result.split(',')[1]
resolve(`data:image/svg+xml;base64,${base64}`)
}
reader.onerror = reject
reader.readAsDataURL(blob)
})
}
/**
* @Description: 判断数据类型
* @Params: 参数描述
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment