mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:39:05 +08:00
feat: input-excel 支持 xls 格式上传 (#6753)
* feat: input-excel 支持 xls 格式上传 * 避免误修改文件
This commit is contained in:
parent
f712db65c6
commit
b894c36fa8
@ -13,6 +13,8 @@ order: 14
|
||||
1. 节省后端开发成本,无需再次解析 Excel
|
||||
2. 可以前端实时预览效果,比如配合 input-table 组件进行二次修改
|
||||
|
||||
> 2.10.0 以上版本支持 xls 文件格式,2.9.0 及以下版本只支持 xlsx
|
||||
|
||||
## 基本使用
|
||||
|
||||
默认情况下只解析第一个 sheet 的内容,下面的例子中,选择上传文件后,就能知道最终会解析成什么数据
|
||||
|
@ -466,6 +466,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
'!echarts-stat/**',
|
||||
'!papaparse/**',
|
||||
'!exceljs/**',
|
||||
'!xlsx/**',
|
||||
'!docsearch.js/**',
|
||||
'!monaco-editor/**.css',
|
||||
'!amis-ui/lib/components/RichText.js',
|
||||
@ -506,6 +507,8 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
|
||||
'exceljs.js': ['exceljs/**'],
|
||||
|
||||
'xlsx.js': ['xlsx/**'],
|
||||
|
||||
'markdown.js': [
|
||||
'amis-ui/lib/components/Markdown.js',
|
||||
'highlight.js/**',
|
||||
@ -547,6 +550,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
'!echarts/**',
|
||||
'!papaparse/**',
|
||||
'!exceljs/**',
|
||||
'!xlsx/**',
|
||||
'!highlight.js/**',
|
||||
'!argparse/**',
|
||||
'!entities/**',
|
||||
@ -758,6 +762,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
'!echarts-stat/**',
|
||||
'!papaparse/**',
|
||||
'!exceljs/**',
|
||||
'!xlsx/**',
|
||||
'!docsearch.js/**',
|
||||
'!monaco-editor/**.css',
|
||||
'!src/components/RichText.tsx',
|
||||
@ -803,6 +808,8 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
|
||||
'pkg/exceljs.js': ['exceljs/**'],
|
||||
|
||||
'pkg/xlsx.js': ['xlsx/**'],
|
||||
|
||||
'pkg/barcode.js': ['amis-ui/lib/components/BarCode.tsx', 'jsbarcode/**'],
|
||||
|
||||
'pkg/markdown.js': [
|
||||
@ -857,6 +864,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
|
||||
'!echarts/**',
|
||||
'!papaparse/**',
|
||||
'!exceljs/**',
|
||||
'!xlsx/**',
|
||||
'!amis-core/lib/utils/markdown.ts',
|
||||
'!highlight.js/**',
|
||||
'!argparse/**',
|
||||
|
@ -69,7 +69,8 @@
|
||||
"react-transition-group": "4.4.2",
|
||||
"sortablejs": "1.15.0",
|
||||
"tslib": "^2.3.1",
|
||||
"video-react": "0.15.0"
|
||||
"video-react": "0.15.0",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
|
@ -89,56 +89,76 @@ export default class ExcelControl extends React.PureComponent<
|
||||
|
||||
@autobind
|
||||
handleDrop(files: File[]) {
|
||||
const {allSheets, onChange, parseImage} = this.props;
|
||||
const excel = files[0];
|
||||
const fileName = excel.name;
|
||||
const reader = new FileReader();
|
||||
reader.readAsArrayBuffer(excel);
|
||||
reader.onload = async () => {
|
||||
if (reader.result) {
|
||||
import('exceljs').then(async (ExcelJS: any) => {
|
||||
this.ExcelJS = ExcelJS;
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(reader.result);
|
||||
let sheetsResult: any = [];
|
||||
if (allSheets) {
|
||||
workbook.eachSheet((worksheet: any) => {
|
||||
if (parseImage) {
|
||||
sheetsResult.push({
|
||||
sheetName: worksheet.name,
|
||||
data: this.readWorksheet(worksheet),
|
||||
images: this.readImages(worksheet, workbook)
|
||||
});
|
||||
} else {
|
||||
sheetsResult.push({
|
||||
sheetName: worksheet.name,
|
||||
data: this.readWorksheet(worksheet)
|
||||
});
|
||||
// 如果是 xls 就用 xlsx 解析一下转成 xlsx 然后用 exceljs 解析
|
||||
// 为啥不直接用 xlsx 解析内容?因为它的社区版本不支持读图片,只有收费版才支持
|
||||
if (fileName.toLowerCase().endsWith('.xls')) {
|
||||
import('xlsx').then(XLSX => {
|
||||
const workbook = XLSX.read(
|
||||
new Uint8Array(reader.result as ArrayBuffer),
|
||||
{
|
||||
cellDates: true
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const worksheet = workbook.worksheets[0];
|
||||
|
||||
if (parseImage) {
|
||||
const images = this.readImages(worksheet, workbook);
|
||||
sheetsResult = {
|
||||
data: this.readWorksheet(worksheet),
|
||||
images
|
||||
};
|
||||
} else {
|
||||
sheetsResult = this.readWorksheet(worksheet);
|
||||
}
|
||||
}
|
||||
const dispatcher = await this.dispatchEvent('change', sheetsResult);
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
}
|
||||
onChange(sheetsResult);
|
||||
this.setState({filename: files[0].name});
|
||||
});
|
||||
);
|
||||
const xlsxFile = XLSX.writeXLSX(workbook, {type: 'array'});
|
||||
this.processExcelFile(xlsxFile, fileName);
|
||||
});
|
||||
} else {
|
||||
this.processExcelFile(reader.result, fileName);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
processExcelFile(excelData: ArrayBuffer | string, fileName: string) {
|
||||
const {allSheets, onChange, parseImage} = this.props;
|
||||
import('exceljs').then(async (ExcelJS: any) => {
|
||||
this.ExcelJS = ExcelJS;
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(excelData);
|
||||
let sheetsResult: any = [];
|
||||
if (allSheets) {
|
||||
workbook.eachSheet((worksheet: any) => {
|
||||
if (parseImage) {
|
||||
sheetsResult.push({
|
||||
sheetName: worksheet.name,
|
||||
data: this.readWorksheet(worksheet),
|
||||
images: this.readImages(worksheet, workbook)
|
||||
});
|
||||
} else {
|
||||
sheetsResult.push({
|
||||
sheetName: worksheet.name,
|
||||
data: this.readWorksheet(worksheet)
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const worksheet = workbook.worksheets[0];
|
||||
|
||||
if (parseImage) {
|
||||
const images = this.readImages(worksheet, workbook);
|
||||
sheetsResult = {
|
||||
data: this.readWorksheet(worksheet),
|
||||
images
|
||||
};
|
||||
} else {
|
||||
sheetsResult = this.readWorksheet(worksheet);
|
||||
}
|
||||
}
|
||||
const dispatcher = await this.dispatchEvent('change', sheetsResult);
|
||||
if (dispatcher?.prevented) {
|
||||
return;
|
||||
}
|
||||
onChange(sheetsResult);
|
||||
this.setState({filename: fileName});
|
||||
});
|
||||
}
|
||||
|
||||
/** 读取工作表里的图片 */
|
||||
readImages(worksheet: any, workbook: any) {
|
||||
const {imageDataURI} = this.props;
|
||||
@ -319,7 +339,7 @@ export default class ExcelControl extends React.PureComponent<
|
||||
<Dropzone
|
||||
key="drop-zone"
|
||||
onDrop={this.handleDrop}
|
||||
accept=".xlsx"
|
||||
accept=".xlsx,.xls"
|
||||
multiple={false}
|
||||
disabled={disabled}
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user