|
@@ -2,7 +2,554 @@
|
|
|
* Created by Syusuke on 2017/3/17.
|
|
|
*/
|
|
|
|
|
|
+//转换excel相关
|
|
|
+//Excel中人材机的数据不存在合并列
|
|
|
+const TransferExcel = (function () {
|
|
|
+ const $transferModal = $('#transfer');
|
|
|
+ const $file = $('#transfer-file');
|
|
|
+ const $transfer = $('#transferConfirm');
|
|
|
+ const $exportSpread = $('#exportSpread');
|
|
|
+ let exportSpread = null;
|
|
|
+ let transferData = [];
|
|
|
+ //--以防需要可配置的情况
|
|
|
+ const fixedCount = 4; //固定列数(顺序号、项目、单位、代号)
|
|
|
+ const beginCol = 0;//起始的列
|
|
|
+ //固定的这几列的列号映射是动态的,因为有一些子表,这些列进行了合并列的处理
|
|
|
+ let colMapping = {
|
|
|
+ serialNo: 0,
|
|
|
+ name: 1,
|
|
|
+ unit: 2,
|
|
|
+ code: 3,
|
|
|
+ consumeAmt: 4, //消耗量开始的列
|
|
|
+ };
|
|
|
+ //---
|
|
|
+ function isUnDef(v) {
|
|
|
+ return typeof v === 'undefined' || v === null;
|
|
|
+ }
|
|
|
+ //取消所有空格
|
|
|
+ function trimAll(v) {
|
|
|
+ return typeof v === 'string' ? v.replace(/\s/g, '') : v;
|
|
|
+ }
|
|
|
+ //单元格是否有数据
|
|
|
+ function cellHasData(cell) {
|
|
|
+ return cell && cell.value;
|
|
|
+ }
|
|
|
+ //行是否有数据
|
|
|
+ //@param {Object}rowData(行数据) {Array}deduct(排除的列)
|
|
|
+ function rowHasData(rowData, deduct = null) {
|
|
|
+ for (let col in rowData) {
|
|
|
+ if (deduct && deduct.includes(col)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ let cell = rowData[col];
|
|
|
+ if (cell && cell.value) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //行为列头行 //第一列为数值,且后面其他列有数据(不单纯认为是第二列,因为怕有合并序号列)
|
|
|
+ function headerRow(rowData) {
|
|
|
+ return rowData[0] && rowData[0].value && /^\d+$/.test(rowData[0].value) && rowHasData(rowData, ['0']);
|
|
|
+
|
|
|
+ }
|
|
|
+ //去除定额子表数组中的空行(有的表格是在 单位:xx 下面还跟着一些垃圾数据,导致subRation的range范围判定变大了,但是四列后面的数据是空的)
|
|
|
+ function simplifyRationTable(arr) {
|
|
|
+ let target = [];
|
|
|
+ for (let subArr of arr) {
|
|
|
+ let emptyRow = subArr.every(function (ele) {
|
|
|
+ return ele === null;
|
|
|
+ });
|
|
|
+ if (emptyRow) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ target.push(subArr);
|
|
|
+ }
|
|
|
+ return target;
|
|
|
+ }
|
|
|
+ //将二维数组转换成每个元素都有值的二维数据(去没值元素,因为前四列有可能合并列)
|
|
|
+ function simplifyGljTable(arr) {
|
|
|
+ let target = [];
|
|
|
+ for (let subArr of arr) {
|
|
|
+ let subTarget = [];
|
|
|
+ for (let ele of subArr) {
|
|
|
+ if (ele !== null) {
|
|
|
+ subTarget.push(ele);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ target.push(subTarget);
|
|
|
+ }
|
|
|
+ return target;
|
|
|
+ }
|
|
|
+ //获取前固定四列的动态列映射(解决这几列可能有合并列的问题)
|
|
|
+ function getColMapping(rowData, colCount) {
|
|
|
+ function getUndefinedField(obj) {
|
|
|
+ let needFields = ['serialNo', 'name', 'unit', 'code', 'consumeAmt'];
|
|
|
+ for (let field of needFields) {
|
|
|
+ if (!obj.hasOwnProperty(field)) {
|
|
|
+ return field;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //假定序号列为第一列
|
|
|
+ let mapping = {serialNo: 0};
|
|
|
+ for (let i = 1; i < colCount; i++) {
|
|
|
+ let col = beginCol + i,
|
|
|
+ cell = rowData[col];
|
|
|
+ //还没设置的字段(必须要有的是serialNo, name, unit, code, consumeAmt)
|
|
|
+ if (cell && cell.value) {
|
|
|
+ let field = getUndefinedField(mapping);
|
|
|
+ if (field) {
|
|
|
+ mapping[field] = col;
|
|
|
+ }
|
|
|
+ if (typeof mapping.consumeAmt !== 'undefined') {
|
|
|
+ return mapping;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取表头定额名称数据(最后一行为定额末位编码)
|
|
|
+ //合并的单元格处理:为了更好的让定额获得对应的定额名称,将合并单元格做填值处理, eg: [a]['合并'] = [a][a]
|
|
|
+ //@param {Object}dataTable {Object}range(表头的范围,row, col, rowCount, colCount) {Array}spans(spread解析Excel后的合并数组)
|
|
|
+ //@return {Array}
|
|
|
+ function getSubRationTable(dataTable, range, spans) {
|
|
|
+ let subTable = [];
|
|
|
+ for (let i = 0; i < range.rowCount; i++) {
|
|
|
+ subTable.push(Array(range.colCount).fill(null));
|
|
|
+ }
|
|
|
+ //获取合并的单元格填充数据
|
|
|
+ let fillArr = [];
|
|
|
+ for (let i = 0; i < range.rowCount; i++) {
|
|
|
+ let row = range.row + i;
|
|
|
+ if (!dataTable[row]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (let j = 0; j < range.colCount; j++) {
|
|
|
+ let col = range.col + j;
|
|
|
+ let cell = dataTable[row][col];
|
|
|
+ //只有有值的单元格,判断合并才有意义,有值且合并列的单元格,每列的值认为都是一样的
|
|
|
+ if (cellHasData(cell)) {
|
|
|
+ //是否合并了单元格
|
|
|
+ let span = spans.find(function (data) {
|
|
|
+ return data.row === row && data.col === col;
|
|
|
+ });
|
|
|
+ //这个fillData给subData填值用
|
|
|
+ let fillData = {value: trimAll(cell.value), range: {row: i, col: j}};
|
|
|
+ if (span) {
|
|
|
+ fillData.range.rowCount = span.rowCount;
|
|
|
+ fillData.range.colCount = span.colCount;
|
|
|
+ } else {
|
|
|
+ fillData.range.rowCount = 1;
|
|
|
+ fillData.range.colCount = 1;
|
|
|
+ }
|
|
|
+ fillArr.push(fillData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //将数据填充到subData中
|
|
|
+ for (let fillData of fillArr) {
|
|
|
+ //合并行不需要向下填值(否则会重复)
|
|
|
+ let row = fillData.range.row;
|
|
|
+ //合并列需要向右填值
|
|
|
+ for (let j = 0; j < fillData.range.colCount; j++) {
|
|
|
+ let col = fillData.range.col + j;
|
|
|
+ subTable[row][col] = trimAll(fillData.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return simplifyRationTable(subTable);
|
|
|
+ }
|
|
|
+ //获取工料机子表数据(序号至最末消耗量)
|
|
|
+ //@param {Object}dataTable {Object}range(工料机子表的范围,row, col, rowCount, colCount)
|
|
|
+ //@return {Array}
|
|
|
+ function getSubGljTable(dataTable, range) {
|
|
|
+ let gljTable = [];
|
|
|
+ for (let i = 0; i < range.rowCount; i++) {
|
|
|
+ gljTable.push(Array(range.colCount).fill(null));
|
|
|
+ }
|
|
|
+ for (let i = 0; i < range.rowCount; i++) {
|
|
|
+ let row = range.row + i;
|
|
|
+ if (!dataTable[row]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (let j = 0; j < range.colCount; j++) {
|
|
|
+ let col = range.col + j;
|
|
|
+ let cell = dataTable[row][col];
|
|
|
+ if (cellHasData(cell)) {
|
|
|
+ gljTable[i][j] = cell.value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //工料机数据每个单元格应该都有值,没有的为合并列造成,这里将没值的单元格去除
|
|
|
+
|
|
|
+ return simplifyGljTable(gljTable);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * 从原本的excel中提取数据
|
|
|
+ * 需要的数据结构:eg: [{code: '1-1-1', name: '伐树', unit: '表列单位', subTable: [{subGlj: [], subRation: []}]}]
|
|
|
+ * subTable为定额数据对应的子表数据,其中有定额名称子表、工料机子表
|
|
|
+ * */
|
|
|
+ function extractDataFromExcel(sheetData) {
|
|
|
+ let dataTable = sheetData.data.dataTable,
|
|
|
+ spans = sheetData.spans;
|
|
|
+ //行数据是定额行 eg: 1-1-1 人工挖土方
|
|
|
+ //@param {Number}row
|
|
|
+ //@return {Object || Null} eg: {code: '1-1-1', name: '人工挖土方'}
|
|
|
+ function rationRow(row) {
|
|
|
+ let cell = dataTable[row][beginCol];
|
|
|
+ if (!cell || !cell.value || typeof cell.value !== 'string') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ let v = trimAll(cell.value);
|
|
|
+ //[\-,—,一] 这里是因为pdf转出来的excel(需要转换的excel)会吧"-"显示成各种奇怪的横杆
|
|
|
+ //第一数值限制在3位以内,防止有: 2019-05-01等日期干扰
|
|
|
+ let reg = /^(\d{1,3}[\-,_,—,一]{1}\d+[\-,_,—,一]{1}\d+)(\w{0,}[\u4e00-\u9fa5]{1,})/;
|
|
|
+ let match = reg.exec(v);
|
|
|
+ if (match && match.length === 3 && match[0] && match[1] && match[2]) {
|
|
|
+ return {code: match[1].replace(/[_,—,一]/g, '-'), name: match[2]};
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //单位数据行 eg: 单位:表列单位
|
|
|
+ //@return {String || Null} eg: '表列单位'
|
|
|
+ function unitRow(row) {
|
|
|
+ let cell = dataTable[row][beginCol];
|
|
|
+ if (!cell || !cell.value || typeof cell.value !== 'string') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ let v = trimAll(cell.value);
|
|
|
+ let reg = /单位[\:, :]([\w+, \u4e00-\u9fa5]{0,})/;
|
|
|
+ let match = reg.exec(v);
|
|
|
+ if (match && match.length === 2 && match[0] && match[1]) {
|
|
|
+ return match[1];
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //行数据是人材机数据行
|
|
|
+ //表头后,某行第一列为数值,第二列有值,则该行为紧接着表头的人材机数据行
|
|
|
+ //@return {Boolean}
|
|
|
+ function rowIsGlj(rowData) {
|
|
|
+ let numberCell = rowData[colMapping.serialNo],
|
|
|
+ valueCell = rowData[colMapping.name];
|
|
|
+ return numberCell && numberCell.value && /^\d+$/.test(numberCell.value) && valueCell && Boolean(valueCell.value);
|
|
|
+ }
|
|
|
+ //连续有数据的列数(每个子表格中工料机的数据列数)
|
|
|
+ //由于序号、项目、单位、代号可能存在合并列,因此从消耗量列(消耗量列不会合并列,消耗量对应的列号已在getColMapping获取)开始统计
|
|
|
+ function getDataCount(row) {
|
|
|
+ let consumeAmtCol = colMapping.consumeAmt;
|
|
|
+ for (let col = consumeAmtCol; col < sheetData.columnCount; col++) {
|
|
|
+ let cell = dataTable[row][col];
|
|
|
+ if (!cell || !cell.value) {
|
|
|
+ return col;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sheetData.columnCount;
|
|
|
+ }
|
|
|
+ //获取表格的子表范围(定额名称表头范围、工料机数据范围)
|
|
|
+ //遇到单位:xx行rowA后,获取紧跟其后的表格,该表格最少要有一行工料机数据行rowB,表头范围则为rowA至rowB
|
|
|
+ //@param {Number}beginRow
|
|
|
+ function getTableRange(beginRow) {
|
|
|
+ let hasTHead = false,
|
|
|
+ hasTable = false,
|
|
|
+ hasMapping = false; //是否获取过固定列映射
|
|
|
+ let range = {
|
|
|
+ subRation: {},
|
|
|
+ subGlj: {},
|
|
|
+ };
|
|
|
+ for (let row = beginRow; row < sheetData.rowCount; row++) {
|
|
|
+ if (!dataTable[row]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //第一个有数据的行,为表头第一行
|
|
|
+ if (rowHasData(dataTable[row]) && !hasTHead) {
|
|
|
+ hasTHead = true;
|
|
|
+ range.subRation.row = row;
|
|
|
+ }
|
|
|
+ //获取当前子表的固定列映射
|
|
|
+ if (hasTHead && !hasTable && !hasMapping && headerRow(dataTable[row])) {
|
|
|
+ hasMapping = true;
|
|
|
+ colMapping = getColMapping(dataTable[row], sheetData.columnCount);
|
|
|
+ if (!colMapping) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //第一条工料机数据行
|
|
|
+ if (hasTHead && !hasTable && colMapping && rowIsGlj(dataTable[row])) {
|
|
|
+ hasTable = true;
|
|
|
+ range.subGlj.row = row;
|
|
|
+ range.subGlj.col = 0;
|
|
|
+ range.subRation.col = colMapping.consumeAmt;
|
|
|
+ range.subRation.rowCount = range.subGlj.row - range.subRation.row;
|
|
|
+ range.subGlj.colCount = getDataCount(row);
|
|
|
+ range.subRation.colCount = range.subGlj.colCount - colMapping.consumeAmt;
|
|
|
+ }
|
|
|
+ if (hasTable && !rowIsGlj(dataTable[row])) {
|
|
|
+ range.subGlj.rowCount = row - range.subGlj.row;
|
|
|
+ return range;
|
|
|
+ }
|
|
|
+ if (hasTable && (row === sheetData.rowCount - 1 || !dataTable[row + 1])) {
|
|
|
+ range.subGlj.rowCount = row - range.subGlj.row + 1;
|
|
|
+ return range;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //分析整个表
|
|
|
+ let extractData = [];
|
|
|
+ //定额行后必须要跟着单位行
|
|
|
+ let hasUnit = false;
|
|
|
+ for (let row = 0; row < sheetData.rowCount; row++) {
|
|
|
+ if (!dataTable[row] || !rowHasData(dataTable[row])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ let rationData = rationRow(row);
|
|
|
+ if (rationData) {
|
|
|
+ if (!hasUnit) {
|
|
|
+ extractData.pop();
|
|
|
+ }
|
|
|
+ hasUnit = false;
|
|
|
+ //转换数据数组的每个元素,为定额基本数据:不完整的code、不完整的name、unit、和子表门构成
|
|
|
+ //subTable: [{subRation: [], subGlj: []}],subRation为每个子表表头数据(排除掉了顺序号至代号),
|
|
|
+ //subGlj为每个子表工料机数据
|
|
|
+ let basicData = {
|
|
|
+ code: rationData.code,
|
|
|
+ name: rationData.name,
|
|
|
+ unit: null,
|
|
|
+ subTable: []
|
|
|
+ };
|
|
|
+ extractData.push(basicData);
|
|
|
+ }
|
|
|
+ let unitData = unitRow(row);
|
|
|
+ if (unitData) {
|
|
|
+ hasUnit = true;
|
|
|
+ let thisBasicData = extractData[extractData.length - 1];
|
|
|
+ if (thisBasicData) {
|
|
|
+ if (!thisBasicData.unit) {
|
|
|
+ thisBasicData.unit = unitData;
|
|
|
+ }
|
|
|
+ //获取表格数据
|
|
|
+ let range = getTableRange(row + 1);
|
|
|
+ if (range) {
|
|
|
+ let subRationTable = getSubRationTable(dataTable, range.subRation, spans),
|
|
|
+ subGljTable = getSubGljTable(dataTable, range.subGlj);
|
|
|
+ thisBasicData.subTable.push({subRation: subRationTable, subGlj: subGljTable});
|
|
|
+ //跳过其中的行
|
|
|
+ row = range.subGlj.row + range.subGlj.rowCount - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return extractData;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * 转换数据,将提取出来的数据转换成另外一种数据结构,便于转化Excel的结构
|
|
|
+ * 需要的数据结构: eg: [{code: '1-1-1-1', name: '伐树xxx', unit: '表列单位', gljList: [{code,name,unit,comsumeAmt}]}]
|
|
|
+ * */
|
|
|
+ function transferDataFromExtract(extractData) {
|
|
|
+ //从一个提取的数据(1定额数据及其子表数据)中获取一份转换数据
|
|
|
+ function transfer(source) {
|
|
|
+ //以完整定额编码为属性,因为1个定额可能会有多张子表,且完整定额编码相同,子工料机不同,方便直接添加后续的工料机
|
|
|
+ let temp = {},
|
|
|
+ target = [];
|
|
|
+ let basicCode = source.code,
|
|
|
+ basicName = source.name,
|
|
|
+ basicUnit = source.unit;
|
|
|
+ //处理消耗量,可能有(3.5) 和 - 的情况, 处理:(3.5) => 3.5 - => 0
|
|
|
+ function handleConsumeAmt(consumeAmt) {
|
|
|
+ if (typeof consumeAmt === 'string') {
|
|
|
+ consumeAmt = trimAll(consumeAmt);
|
|
|
+ consumeAmt = consumeAmt.replace(/[\-,_,—,一,\(,\),(,)]/g, '');
|
|
|
+ if (!consumeAmt) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return consumeAmt;
|
|
|
+ }
|
|
|
+ //从工料机子表中获取工料机数据, index为定额编码对应的下标索引
|
|
|
+ function getGljList(gljTable, index) {
|
|
|
+ let gljList = [];
|
|
|
+ //获取的工料机对应列
|
|
|
+ let gljColMapping = {
|
|
|
+ name: 1,
|
|
|
+ unit: 2,
|
|
|
+ code: 3,
|
|
|
+ consumeAmtCol: fixedCount + index
|
|
|
+ };
|
|
|
+ for (let rowData of gljTable) {
|
|
|
+ //工料机数据必须要有名称、单位、编码
|
|
|
+ if (!rowData[gljColMapping.name] ||
|
|
|
+ !rowData[gljColMapping.unit] ||
|
|
|
+ !rowData[gljColMapping.code]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ let consumeAmt = isUnDef(rowData[gljColMapping.consumeAmtCol]) ? 0 : handleConsumeAmt(rowData[gljColMapping.consumeAmtCol]);
|
|
|
+ gljList.push({
|
|
|
+ name: rowData[gljColMapping.name],
|
|
|
+ unit: rowData[gljColMapping.unit],
|
|
|
+ code: rowData[gljColMapping.code],
|
|
|
+ consumeAmt: consumeAmt,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return gljList;
|
|
|
+ }
|
|
|
+ //拼接定额工料机数据
|
|
|
+ for (let table of source.subTable) {
|
|
|
+ let rationTable = table.subRation;
|
|
|
+ if (!rationTable || rationTable.length === 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ let lastRationCodes = rationTable.pop(); //定额子表,最后一行是末位定额编码
|
|
|
+ for (let i = 0; i < lastRationCodes.length; i++) {
|
|
|
+ let lastCode = lastRationCodes[i];
|
|
|
+ //拼接定额编码
|
|
|
+ let compleCode = `${basicCode}-${lastCode}`,
|
|
|
+ gljList = getGljList(table.subGlj, i);
|
|
|
+ if (!temp[compleCode]) { //该定额不存在
|
|
|
+ temp[compleCode] = {
|
|
|
+ code: compleCode,
|
|
|
+ unit: basicUnit,
|
|
|
+ name: basicName,
|
|
|
+ gljList: gljList
|
|
|
+ };
|
|
|
+ } else { //该定额已存在,则追加工料机
|
|
|
+ temp[compleCode].gljList = temp[compleCode].gljList.concat(gljList);
|
|
|
+ }
|
|
|
+ //拼接定额名称
|
|
|
+ for (let rationNameRow of rationTable) {
|
|
|
+ if (rationNameRow[i]) {
|
|
|
+ temp[compleCode].name += ` ${rationNameRow[i]}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //将temp对象转换为数据
|
|
|
+ for (let code in temp) {
|
|
|
+ target.push(temp[code]);
|
|
|
+ }
|
|
|
+ return target;
|
|
|
+ }
|
|
|
+ let transferData = [];
|
|
|
+ for (let data of extractData) {
|
|
|
+ let unitTargetData = transfer(data);
|
|
|
+ transferData = transferData.concat(unitTargetData);
|
|
|
+ }
|
|
|
+ return transferData;
|
|
|
+ }
|
|
|
+ //导入Excel
|
|
|
+ function exportToExcel(transferData, fileName) {
|
|
|
+ $.bootstrapLoading.start();
|
|
|
+ setTimeout(function () {
|
|
|
+ if (exportSpread) {
|
|
|
+ exportSpread.destroy();
|
|
|
+ }
|
|
|
+ exportSpread = new GC.Spread.Sheets.Workbook($exportSpread[0], {sheetCount: 1});
|
|
|
+ let sheet = exportSpread.getSheet(0);
|
|
|
+ sheet.suspendPaint();
|
|
|
+ sheet.suspendEvent();
|
|
|
+ //往表格填值
|
|
|
+ let curRow = 0,
|
|
|
+ fillCol = {
|
|
|
+ code: 1,
|
|
|
+ name: 2,
|
|
|
+ unit: 3,
|
|
|
+ consumeAmt: 4
|
|
|
+ };
|
|
|
+ function getRowCount() {
|
|
|
+ let count = 0;
|
|
|
+ for (let data of transferData) {
|
|
|
+ count += 1 + data.gljList.length;
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+ sheet.setRowCount(getRowCount());
|
|
|
+ for (let data of transferData) {
|
|
|
+ sheet.setValue(curRow, 0, '定额');
|
|
|
+ sheet.setValue(curRow, fillCol.code, data.code);
|
|
|
+ sheet.setValue(curRow, fillCol.name, data.name);
|
|
|
+ sheet.setValue(curRow, fillCol.unit, data.unit);
|
|
|
+ curRow++;
|
|
|
+ for (let glj of data.gljList) {
|
|
|
+ sheet.setValue(curRow, fillCol.code, glj.code);
|
|
|
+ sheet.setValue(curRow, fillCol.name, glj.name);
|
|
|
+ sheet.setValue(curRow, fillCol.unit, glj.unit);
|
|
|
+ sheet.setValue(curRow, fillCol.consumeAmt, glj.consumeAmt);
|
|
|
+ curRow++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sheet.resumeEvent();
|
|
|
+ sheet.resumePaint();
|
|
|
+ let json = exportSpread.toJSON();
|
|
|
+ let excelIo = new GC.Spread.Excel.IO();
|
|
|
+ excelIo.save(json, function(blob) {
|
|
|
+ saveAs(blob, fileName);
|
|
|
+ $.bootstrapLoading.end();
|
|
|
+ $transferModal.modal('hide');
|
|
|
+ }, function(e) {
|
|
|
+ $.bootstrapLoading.end();
|
|
|
+ $transferModal.modal('hide');
|
|
|
+ console.log(e);
|
|
|
+ });
|
|
|
+ }, 200);
|
|
|
+ }
|
|
|
+ function eventListener() {
|
|
|
+ $transferModal.on('hidden.bs.modal', function () {
|
|
|
+ $file.val('');
|
|
|
+ transferData = [];
|
|
|
+ });
|
|
|
+ //导入excel,提取并转换定额数据
|
|
|
+ $file.change(function () {
|
|
|
+ $transfer.addClass('disabled');
|
|
|
+ let file = $(this)[0];
|
|
|
+ let excelFile = file.files[0];
|
|
|
+ if(excelFile) {
|
|
|
+ let xlsReg = /xls$/g;
|
|
|
+ if(excelFile.name && xlsReg.test(excelFile.name)){
|
|
|
+ alert('请选择xlsx文件');
|
|
|
+ $(this).val('');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $.bootstrapLoading.start();
|
|
|
+ $('#loadingPage').css('z-index', '2000');
|
|
|
+ //前端解析excel数据
|
|
|
+ let excelIo = new GC.Spread.Excel.IO();
|
|
|
+ let sDate = +new Date();
|
|
|
+ excelIo.open(excelFile, function (json) {
|
|
|
+ console.log(json);
|
|
|
+ let extractData = extractDataFromExcel(json.sheets.Sheet1);
|
|
|
+ transferData = transferDataFromExtract(extractData);
|
|
|
+ console.log(`解析Excel文件时间:${+new Date() - sDate}`);
|
|
|
+ $.bootstrapLoading.end();
|
|
|
+ $transfer.removeClass('disabled');
|
|
|
+ }, function (e) {
|
|
|
+ $.bootstrapLoading.end();
|
|
|
+ $transfer.removeClass('disabled');
|
|
|
+ alert(e.errorMessage);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //确认转换,导出转换的Excel
|
|
|
+ $transfer.click(function () {
|
|
|
+ if (!transferData || transferData.length === 0) {
|
|
|
+ //没有转换数据
|
|
|
+ alert('没有转换数据');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let fileName = '转换数据.xlsx';
|
|
|
+ if ($file[0].files && $file[0].files[0] && $file[0].files[0].name) {
|
|
|
+ fileName = '转换数据' + $file[0].files[0].name;
|
|
|
+ }
|
|
|
+ exportToExcel(transferData, fileName);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return {eventListener}
|
|
|
+})();
|
|
|
+
|
|
|
$(function () {
|
|
|
+ TransferExcel.eventListener();
|
|
|
+
|
|
|
let dispNameArr;
|
|
|
let preDeleteId = null;
|
|
|
let deleteCount = 0;
|
|
@@ -292,6 +839,7 @@ function getAllRationLib(callback){
|
|
|
"<td><a class='btn btn-secondary btn-sm import-source' href='javacript:void(0);' data-id='"+ id +"' title='导入原始数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
|
|
|
"<td><a class='btn btn-success btn-sm export' href='javacript:void(0);' data-toggle='modal' data-id='"+ id +"' data-target='#emport' title='导出内部数据'><i class='fa fa-sign-out fa-rotate-270'></i>导出</a> " +
|
|
|
"<a class='btn btn-secondary btn-sm import-data' href='javacript:void(0);' data-id='"+ id +"' title='导入内部数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
|
|
|
+ "<td><a class='btn btn-secondary btn-sm transfer-excel' data-toggle='modal' data-target='#transfer' href='javacript:void(0);' data-id='"+ id +"' title='转换Excel'><i class='fa fa-sign-in fa-rotate-90'></i>转换</a></td>" +
|
|
|
"<td><a class='btn btn-secondary btn-sm set-comple' href='javacript:void(0);' data-id='"+ id +"' title='将章节树设为补充模板数据'><i class='fa fa-sign-in fa-rotate-90'></i>设置</a></td>" +
|
|
|
"</tr>");
|
|
|
$("#tempId").attr("id", id);
|
|
@@ -380,6 +928,7 @@ function createRationLib(rationObj, dispNamesArr){
|
|
|
"<td><a class='btn btn-secondary btn-sm import-source' href='javacript:void(0);' data-id='"+ id +"' title='导入原始数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
|
|
|
"<td><a class='btn btn-success btn-sm export' href='javacript:void(0);' data-toggle='modal' data-id='"+ id +"' data-target='#emport' title='导出内部数据'><i class='fa fa-sign-out fa-rotate-270'></i>导出</a> " +
|
|
|
"<a class='btn btn-secondary btn-sm import-data' href='javacript:void(0);' data-id='"+ id +"' title='导入内部数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
|
|
|
+ "<td><a class='btn btn-secondary btn-sm transfer-excel' data-toggle='modal' data-target='#transfer' href='javacript:void(0);' data-id='"+ id +"' title='转换Excel'><i class='fa fa-sign-in fa-rotate-90'></i>转换</a></td>" +
|
|
|
"<td><a class='btn btn-secondary btn-sm set-comple' href='javacript:void(0);' data-id='"+ id +"' title='将章节树设为补充模板数据'><i class='fa fa-sign-in fa-rotate-90'></i>设置</a></td>" +
|
|
|
"</tr>");
|
|
|
}
|