Преглед на файлове

1. 下载台账excel
2. 更新模板文件

MaiXinRong преди 5 години
родител
ревизия
1075b3f4ab

+ 10 - 4
app/controller/ledger_controller.js

@@ -22,6 +22,7 @@ const fs = require('fs');
 const LzString = require('lz-string');
 const accountGroup = require('../const/account_group').group;
 const path = require('path');
+const exportExcel = require('../lib/export_excel');
 
 module.exports = app => {
 
@@ -513,12 +514,17 @@ module.exports = app => {
                     let fileName;
                     if (file === '导入分项清单EXCEL格式.xls') {
                         fileName = path.join(this.app.baseDir, 'app', 'public', 'files', 'template', 'ledger', '导入分项清单EXCEL格式.xls');
-                    } else if (file === 'ledger') {
+                        ctx.body = await fs.readFileSync(fileName);
+                    } else if (file === '台账分解.xlsx') {
+                        console.log(file);
                         const create_time = Date.parse(new Date()) / 1000;
-                        fileName = this.app.baseDir + '/app/public/files/downloads/ledger/' + ctx.tender.id + '-' + create_time + '.xlsx';
-                        // todo 导出台账清单Excel
+                        fileName = this.app.baseDir + '/app/public/files/ledger' + ctx.tender.id + '-' + create_time + '.xlsx';
+                        const exportor = new exportExcel.exportLedger2Excel(ctx);
+                        await exportor.export2File(fileName);
+                        ctx.body = await fs.readFileSync(fileName);
+                        // 输出文件后删除
+                        fs.unlinkSync(fileName);
                     }
-                    ctx.body = await fs.readFileSync(fileName);
                 } catch (err) {
                     this.log(err);
                     this.setMessage(err.toString(), this.messageType.ERROR);

+ 1 - 1
app/extend/helper.js

@@ -878,7 +878,7 @@ module.exports = {
             .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v, s: next.s}}), {});
         const sData = data
             .map((v, i) => v.map((k, j) => Object.assign({}, {
-                v: k,
+                v: k ? k : '',
                 s: {alignment: {horizontal: setting.hAlign[j]}},
                 position: String.fromCharCode(65+j) + (i+2) })))
             .reduce((prev, next) => prev.concat(next))

+ 103 - 0
app/lib/export_excel.js

@@ -0,0 +1,103 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+const LedgerTree = require('./ledger');
+const xlsx = require('js-xlsx');
+const measureType = require('../const/tender').measureType;
+
+class exportExcel {
+
+    constructor(ctx) {
+        this.ctx = ctx;
+        this.setting = null;
+        this.xlsxData = {
+            SheetNames: [],
+            Sheets: {}
+        };
+    }
+
+    export2Sheet(xlsxData, name, data) {
+        if (xlsxData.SheetNames.indexOf(name) >= 0) throw '存在同名Sheet';
+
+        if (this.setting) {
+            xlsxData.SheetNames.push(name);
+            xlsxData.Sheets[name] = this.ctx.helper.simpleXlsxSheetData(this.setting, data);
+        }
+    }
+
+    async export2File(fileName) {
+        this.export2Sheet(this.xlsxData, 'Sheet1', []);
+        xlsx.writeFile(this.xlsxData, fileName);
+    }
+}
+
+class exportLedger2Excel extends exportExcel {
+    constructor(ctx) {
+        super(ctx);
+        this.setting = {
+            header: ['项目节编号', '清单子目号', '部位明细', '名称', '单位', '清单数量', '设计数量1', '设计数量2', '单价', '合价', '图号', '备注'],
+            width: [100, 70, 70, 300, 60, 80, 80, 80, 80, 80, 100, 100],
+            hAlign: ['left', 'left', 'left', 'left','center', 'right', 'right', 'right', 'right', 'right', 'left', 'left'],
+        };
+    }
+
+    async sortLedgerData(billsTree, pos) {
+        const result = [];
+        for (const node of billsTree.nodes) {
+            result.push([node.code, node.b_code, '', node.name, node.unit,
+                node.quantity, node.dgn_qty1, node.dgn_qty2, node.unit_price, node.total_price,
+                node.drawing_code, node.memo
+            ]);
+            const posRange = pos.getLedgerPos(node.id);
+            if (posRange && posRange.length > 0) {
+                for (const [i, p] of posRange.entries()) {
+                    result.push([
+                        '', '', (i + 1) + '', p.name, '',
+                        p.quantity, null, null, null, null,
+                        p.drawing_code, p.memo
+                    ]);
+                }
+            }
+        }
+        return result;
+    }
+
+    async getLedgerMapData() {
+        const billsData = await this.ctx.service.ledger.getData(this.ctx.tender.id);
+        const billsTree = new LedgerTree.billsTree(this.ctx, {
+            id: 'ledger_id',
+            pid: 'ledger_pid',
+            order: 'order',
+            level: 'level',
+            rootId: -1,
+            keys: ['id', 'tender_id', 'ledger_id'],
+            stageId: 'id',
+            calcFields: ['deal_tp', 'total_price']
+        });
+        billsTree.loadDatas(billsData);
+        billsTree.calculateAll();
+
+        const posData = this.ctx.tender.data.measure_type === measureType.tz.value
+            ? await this.ctx.service.pos.getPosData({tid: this.ctx.tender.id}) : [];
+        const pos = new LedgerTree.pos({id: 'id', ledgerId: 'lid'});
+        pos.loadDatas(posData);
+
+        return this.sortLedgerData(billsTree, pos);
+    }
+
+    async export2File(fileName) {
+        const ledgerData = await this.getLedgerMapData();
+        this.export2Sheet(this.xlsxData, '台账分解', ledgerData);
+        xlsx.writeFile(this.xlsxData, fileName);
+    }
+}
+
+module.exports = {
+    exportLedger2Excel
+};

BIN
app/public/deal_bills/template.xls


BIN
app/public/files/template/ledger/导入工程量清单EXCEL格式.xls


+ 3 - 0
app/view/ledger/explode.ejs

@@ -39,6 +39,9 @@
                         <input type="text" class="form-control form-control-sm m-0" id="bills-expr" readonly="">
                     </div>
                 </div>
+                <div class="d-inline-block ml-3">
+                    <a href="/tender/<%- ctx.tender.id %>/ledger/download/台账分解.xlsx" class="btn btn-primary btn-sm">下载台账Excel</a>
+                </div>
             </div>
             <div class="ml-auto">
                 <% if (tender.ledger_status === auditConst.status.checkNo) { %>