|
@@ -0,0 +1,390 @@
|
|
|
+// import XLSX from 'xlsx'
|
|
|
+// import _ from 'lodash'
|
|
|
+// // import ExcelImportDialog from "./renderers/excelImportDialog";
|
|
|
+// import * as path from "path";
|
|
|
+// // import {clearLoading, loading} from "./renderers";
|
|
|
+// // @ts-ignore
|
|
|
+// // import XLSX_EXPORT from 'xlsx_export';
|
|
|
+// // @ts-ignore
|
|
|
+// const XLSX_EXPORT = window.LAY_EXCEL
|
|
|
+//
|
|
|
+// export {XLSX};
|
|
|
+// export {XLSX_EXPORT}
|
|
|
+//
|
|
|
+// export function readExcel(file: File): Promise<any> {
|
|
|
+// return new Promise((resolve, reject) => {
|
|
|
+// var reader = new FileReader();
|
|
|
+// reader.onload = function (e) {
|
|
|
+// if (e.target) {
|
|
|
+// const data = e.target.result;
|
|
|
+// const workbook = XLSX.read(data, {type: 'binary'});
|
|
|
+// resolve(workbook);
|
|
|
+// } else {
|
|
|
+// reject("文件读取失败!!!")
|
|
|
+// }
|
|
|
+// };
|
|
|
+// try {
|
|
|
+// reader.readAsBinaryString(file);
|
|
|
+// } catch (e) {
|
|
|
+// reject(e)
|
|
|
+// }
|
|
|
+// })
|
|
|
+// }
|
|
|
+//
|
|
|
+// export declare interface ErrorMsgDataItem {
|
|
|
+// /** 错误id 由allData 的__importID__字段值 + "_" + field的值 表示哪一行的哪一列出错,行校验错误时候直接为allData 的__importID__ + "" */
|
|
|
+// errorId: string
|
|
|
+// /** 对应数据行 allData 的__importID__字段值 */
|
|
|
+// importID: number
|
|
|
+// /** 字段 */
|
|
|
+// field: string
|
|
|
+// /** 字段值 */
|
|
|
+// title: string
|
|
|
+// /** 字段值 */
|
|
|
+// value: string
|
|
|
+// /** 错误信息 */
|
|
|
+// errormessage: string
|
|
|
+// }
|
|
|
+//
|
|
|
+// export declare interface ImportResult {
|
|
|
+// /** 所有导入的数据,如果有字典会格式化到字典,格式化错误的保持原始值 */
|
|
|
+// allData: any[]
|
|
|
+// /** 导入正确的数据 */
|
|
|
+// okData: any[]
|
|
|
+// /** 导入错误的数据 */
|
|
|
+// errorData: any[]
|
|
|
+// /** 导入错误数据的错误明细 */
|
|
|
+// errorMsgData: ErrorMsgDataItem[]
|
|
|
+// }
|
|
|
+//
|
|
|
+// /** 定义参数列 */
|
|
|
+// export declare interface Field {
|
|
|
+// /** 字段 */
|
|
|
+// dataIndex: string
|
|
|
+// /** 字段名 */
|
|
|
+// header: string
|
|
|
+// /** 校验方法,校验通过返回true, 否则返回错误信息 会记录到错误列表里面 errorMsgData */
|
|
|
+// validate?: ((v: ValidateObject) => true | string) | string
|
|
|
+// /** 格式化,表格显示 兼容默认弹出框表格的formatter */
|
|
|
+// fix?: ((v: any) => any) | string
|
|
|
+// /** 导入格式化 返回null或者undefined 表示格式化错误,会记录到错误列表里面 errorMsgData */
|
|
|
+// importFormatter?: ((v: ValidateObject) => null | undefined | string | number) | string
|
|
|
+// /** 字典, 参与数据校验和表格显示格式化, 校验不通过的,会记录到错误列表里面 errorMsgData 同时兼容默认弹出框表格的字典 */
|
|
|
+// data?: any | { id: string | number, text: string }
|
|
|
+// }
|
|
|
+//
|
|
|
+// /** 格式化及校验的参数 */
|
|
|
+// export declare interface ValidateObject {
|
|
|
+// field: Field
|
|
|
+// ov: any,
|
|
|
+// nv: any,
|
|
|
+// rowIndex: number,
|
|
|
+// data: any,
|
|
|
+// rowDatas: any[],
|
|
|
+// }
|
|
|
+//
|
|
|
+// /** 行数据校验的参数 */
|
|
|
+// export declare interface RowValidateObject {
|
|
|
+// fields: Field[],
|
|
|
+// data: any,
|
|
|
+// rowIndex: number,
|
|
|
+// rowDatas: any[]
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 定义切口,可以在外部修改数据
|
|
|
+// */
|
|
|
+// export declare type AfterClientValidate =
|
|
|
+// ((importResult: ImportResult, resolve: (value?: (ImportResult | PromiseLike<ImportResult> | undefined)) => void) => ImportResult)
|
|
|
+// | undefined
|
|
|
+//
|
|
|
+// export function readExcelWithFieldSet(file: File,
|
|
|
+// fieldSet: any[],
|
|
|
+// dataStartRow: number = 2,
|
|
|
+// titleRowNumber: number = 1,
|
|
|
+// rowValidate: ((rv: RowValidateObject) => true | string) | undefined = undefined,
|
|
|
+// otherValidate: AfterClientValidate = undefined,
|
|
|
+// fieldValidate: ((fields: Field[], columnTitles: string[]) => boolean) | undefined = undefined): Promise<ImportResult> {
|
|
|
+// return new Promise<ImportResult>((resolve, reject) => {
|
|
|
+// setTimeout(()=>{
|
|
|
+// readExcel(file).then(workbook => {
|
|
|
+// const sheetNames = workbook.SheetNames; // 工作表名称集合
|
|
|
+// const worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet
|
|
|
+// const titleRowValue: any[] = [];
|
|
|
+// const titleRowKey: any[] = [];
|
|
|
+// let needLoop: boolean = false; // 是否需要迭代
|
|
|
+// let fields: any[] = [];
|
|
|
+// if (worksheet && worksheet["!ref"]) {
|
|
|
+// const t = worksheet["!ref"];
|
|
|
+// const tempArr = t.split(':');
|
|
|
+// if (tempArr.length >= 2) {
|
|
|
+// let firstRowNumber = tempArr[0].replace(/[^0-9]/ig, "");
|
|
|
+//
|
|
|
+// // 选取title的行,删除之前的行
|
|
|
+// if (titleRowNumber > firstRowNumber) {
|
|
|
+// for (let i = firstRowNumber; i < titleRowNumber; i++) {
|
|
|
+// for (const key in worksheet) {
|
|
|
+// if (key.endsWith(i) && key.replace(/[^0-9]/ig, "") === i) {
|
|
|
+// delete worksheet[key];
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// const fc = tempArr[0].replace(/[^a-z]/ig, "");
|
|
|
+// firstRowNumber = titleRowNumber + '';
|
|
|
+// worksheet["!ref"] = fc+firstRowNumber + ":" + tempArr[1]
|
|
|
+// }
|
|
|
+// const lastRowNumber = tempArr[1].replace(/[^0-9]/ig, "");
|
|
|
+// // const firstColNumber = tempArr[0].split(''+firstRowNumber)[0];
|
|
|
+// // const lastColNumber = tempArr[1].split(''+lastRowNumber)[0];
|
|
|
+// for (const key in worksheet) {
|
|
|
+// if (key.endsWith(firstRowNumber) && key.replace(/[^0-9]/ig, "") === firstRowNumber) {
|
|
|
+// titleRowKey.push(key)
|
|
|
+// titleRowValue.push(worksheet[key].v)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if (fieldSet && fieldSet.length > 0) {
|
|
|
+// let length = fieldSet.length;
|
|
|
+// length = length <= titleRowKey.length ? length : titleRowKey.length;
|
|
|
+// for (let i = 0; i < length; i++) {
|
|
|
+// const vk = titleRowKey[i];
|
|
|
+// const item = fieldSet[i];
|
|
|
+// const field: any = {}
|
|
|
+// if (typeof item === 'string') {
|
|
|
+// field.field = item;
|
|
|
+// field.title = worksheet[vk].v;
|
|
|
+// worksheet[vk] = {t: "s", v: item, h: item, w: item}
|
|
|
+// } else if (typeof item.field === "string") {
|
|
|
+// field.field = item.field;
|
|
|
+// field.title = worksheet[vk].v;
|
|
|
+// worksheet[vk] = {t: "s", v: item.field, h: item.field, w: item.field};
|
|
|
+// if (typeof item.validate === "function") {
|
|
|
+// field.validate = item.validate
|
|
|
+// needLoop = true;
|
|
|
+// }
|
|
|
+// if (typeof item.importFormatter === "function") {
|
|
|
+// field.importFormatter = item.importFormatter
|
|
|
+// needLoop = true;
|
|
|
+// }
|
|
|
+// if ((item.data instanceof Array && item.data.length > 0)
|
|
|
+// || _.isPlainObject(item.data) && Object.keys(item.data).length > 0) {
|
|
|
+// field.data = item.data
|
|
|
+// needLoop = true;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// fields.push(field)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (fieldValidate && typeof fieldValidate === "function") {
|
|
|
+// if (fieldValidate(fields, titleRowValue) !== true) {
|
|
|
+// reject("fields validate error");
|
|
|
+// return
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// const allData = XLSX.utils.sheet_to_json(worksheet);
|
|
|
+// let okData: any[] = [], errorData: any[] = [], errorMsgData: ErrorMsgDataItem[] = [];
|
|
|
+// const needItemLoop = needLoop;
|
|
|
+// if (rowValidate && typeof rowValidate === "function") {
|
|
|
+// needLoop = true;
|
|
|
+// }
|
|
|
+// if (needLoop === true) {
|
|
|
+// for (let index = 0; index < allData.length; index++) {
|
|
|
+// const row: any = allData[index];
|
|
|
+// const rowNumber = dataStartRow + index;
|
|
|
+// row.__importID__ = rowNumber
|
|
|
+// let isRowOk: boolean = true;
|
|
|
+// if (needItemLoop) {
|
|
|
+// for (let num = 0; num < fields.length; num++) {
|
|
|
+// const field = fields[num];
|
|
|
+// const ov = row[field.field];
|
|
|
+// let nv: any = ov;
|
|
|
+//
|
|
|
+// let hasError: boolean = false;
|
|
|
+// const rowNumber = dataStartRow + index;
|
|
|
+// const ei: ErrorMsgDataItem = {
|
|
|
+// errorId: rowNumber + '_' + field.field,
|
|
|
+// importID: rowNumber,
|
|
|
+// field: field.field,
|
|
|
+// title: field.title,
|
|
|
+// value: ov,
|
|
|
+// errormessage: ""
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 格式化
|
|
|
+// if (field.data instanceof Array) {
|
|
|
+// nv = undefined;
|
|
|
+// ei.errormessage = "字典匹配失败"
|
|
|
+// _.forEach(field.data, (v, index) => {
|
|
|
+// if (v.text === ov) {
|
|
|
+// nv = v.id;
|
|
|
+// return
|
|
|
+// }
|
|
|
+// })
|
|
|
+// } else if (_.isPlainObject(field.data)) {
|
|
|
+// nv = undefined;
|
|
|
+// ei.errormessage = "字典匹配失败"
|
|
|
+// _.forEach(field.data, (value, key) => {
|
|
|
+// if (value === ov) {
|
|
|
+// nv = key;
|
|
|
+// return
|
|
|
+// }
|
|
|
+// })
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (field.importFormatter) {
|
|
|
+// const vdata: ValidateObject = {
|
|
|
+// field,
|
|
|
+// ov,
|
|
|
+// nv,
|
|
|
+// rowIndex: index,
|
|
|
+// data: row,
|
|
|
+// rowDatas: allData
|
|
|
+// }
|
|
|
+// nv = undefined;
|
|
|
+// ei.errormessage = "格式化失败";
|
|
|
+// nv = field.importFormatter(vdata)
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (nv === undefined || nv === null) {
|
|
|
+// hasError = true;
|
|
|
+// } else {
|
|
|
+// row[field.field] = nv;
|
|
|
+// ei.errormessage = "";
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 校验
|
|
|
+// if (field.validate) {
|
|
|
+// const vdata: ValidateObject = {
|
|
|
+// field,
|
|
|
+// ov,
|
|
|
+// nv,
|
|
|
+// rowIndex: index,
|
|
|
+// data: row,
|
|
|
+// rowDatas: allData
|
|
|
+// }
|
|
|
+// const errormessage: true | string = field.validate(vdata);
|
|
|
+// if (errormessage === true) {
|
|
|
+//
|
|
|
+// } else {
|
|
|
+// hasError = true;
|
|
|
+// ei.errormessage = ei.errormessage + "/" + errormessage;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if (hasError === true) {
|
|
|
+// isRowOk = false;
|
|
|
+// errorMsgData.push(ei);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if (rowValidate && typeof rowValidate === "function") {
|
|
|
+// const errormessage: true | string = rowValidate({
|
|
|
+// fields,
|
|
|
+// data: row,
|
|
|
+// rowIndex: index,
|
|
|
+// rowDatas: allData
|
|
|
+// })
|
|
|
+// if (errormessage === true) {
|
|
|
+//
|
|
|
+// } else {
|
|
|
+// isRowOk = false;
|
|
|
+//
|
|
|
+// const ei: ErrorMsgDataItem = {
|
|
|
+// errorId: rowNumber + '',
|
|
|
+// field: "row",
|
|
|
+// title: "数据行",
|
|
|
+// value: "当前行的数据",
|
|
|
+// importID: rowNumber,
|
|
|
+// errormessage
|
|
|
+// }
|
|
|
+// errorMsgData.push(ei);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// row.__hasError__ = !isRowOk
|
|
|
+// if (isRowOk === true) {
|
|
|
+// okData.push(row)
|
|
|
+// } else {
|
|
|
+// errorData.push(row)
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// } else {
|
|
|
+// // 添加数据的唯一标识
|
|
|
+// for (let index = 0; index < allData.length; index++) {
|
|
|
+// const row: any = allData[index];
|
|
|
+// const rowNumber = dataStartRow + index;
|
|
|
+// row.__importID__ = rowNumber;
|
|
|
+// row.__hasError__ = false
|
|
|
+// }
|
|
|
+// okData = allData;
|
|
|
+// }
|
|
|
+// if (otherValidate && typeof otherValidate === "function") {
|
|
|
+// otherValidate({allData, okData, errorData, errorMsgData}, resolve);
|
|
|
+// } else {
|
|
|
+// resolve({allData, okData, errorData, errorMsgData});
|
|
|
+// }
|
|
|
+// // clearLoading()
|
|
|
+// })
|
|
|
+// }, 50);
|
|
|
+// })
|
|
|
+// }
|
|
|
+//
|
|
|
+// export declare interface ImportExcelOption {
|
|
|
+// // 字段设置
|
|
|
+// fields: Field[],
|
|
|
+// // 字段校验方法
|
|
|
+// fieldValidate?: ((fields: Field[], columnTitles: string[]) => boolean) | undefined,
|
|
|
+// // 数据行校验方法
|
|
|
+// rowValidate?: ((rv: RowValidateObject) => true | string) | undefined,
|
|
|
+// // 客户端校验完成后调用
|
|
|
+// afterClientValidate?: AfterClientValidate,
|
|
|
+// // Excel起始数据行的的行号 默认给定为2
|
|
|
+// dataStartRow?: number,
|
|
|
+// // Excel标题行的的行号 默认给定为1
|
|
|
+// titleRowNumber?: number,
|
|
|
+// // 导入完成后调用 回传结果数据
|
|
|
+// onImportAfter?: (result: ImportResult) => {}
|
|
|
+// // 隐藏所有数据表格, 默认false
|
|
|
+// hidAllDataGrid?: boolean,
|
|
|
+// // 隐藏正确数据表格 默认 false
|
|
|
+// hidOKDataGrid?: boolean,
|
|
|
+// // 隐藏错误数据的表格 默认false
|
|
|
+// hidErrorDataGrid?: boolean,
|
|
|
+// // 隐藏错误信息表格 默认false
|
|
|
+// hidErrorMsgGrid?: boolean,
|
|
|
+// // 所有数据表格的分页大小, 0 为不分页
|
|
|
+// dataGridPageSize?: 0 | 10 | 20 | 50 | 100 | 200 | 500 | 1000,
|
|
|
+// // 错误信息表格的分页大小, 0 为不分页
|
|
|
+// errorMsgGridPageSize?: 0 | 10 | 20 | 50 | 100 | 200 | 500 | 1000,
|
|
|
+// // 导入模版的名称
|
|
|
+// templateName?: string,
|
|
|
+// // 导入模板下载地址
|
|
|
+// dowLoadUrl?: string,
|
|
|
+// // 标题
|
|
|
+// title?: string,
|
|
|
+// // 弹窗高
|
|
|
+// height?: string,
|
|
|
+// // 弹窗宽
|
|
|
+// width?: string,
|
|
|
+// // 默认显示的表格
|
|
|
+// defaultShowData?: "allData" | "okData" | "errorData",
|
|
|
+// // 自定义错误信息表格的列宽
|
|
|
+// errMsgGridColWidths?: number[],
|
|
|
+// // 外部定义的控件
|
|
|
+// toolBar?: any[],
|
|
|
+// // 关闭回调
|
|
|
+// onClose?: string | (() => void)
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 打开excel导入的方法
|
|
|
+// * @param option 参数配置
|
|
|
+// * @param sender
|
|
|
+// */
|
|
|
+// export function importExcel(option: ImportExcelOption, sender: any): ExcelImportDialog {
|
|
|
+// const dialog = new ExcelImportDialog({option})
|
|
|
+// dialog.showDialog(sender);
|
|
|
+// return dialog
|
|
|
+// }
|