AngularJS 導出Excel指令

Excel導出思路

參考文章 - angularjs使用指令實現table導出csvjavascript

項目中使用到了導出Excel功能,潘老師已經在博客中將表格導出爲csv的技術難點實現,剩下的,只是根據實際的業務需求對該指令進行完善。java

大致遇到了如下幾個問題:angularjs

功能按鈕不導出

clipboard.png

由於原指令默認導出表格全部的內容,第一次直接導出時,發現直接將查看、編輯這幾個按鈕的HTML代碼都導出去了,咱們要的應該是人員信息和人員資質信息。segmentfault

指令添加參數:有效數據列數。數組

如圖,這裏的有效數據列就是市、區縣等等一直到有效期至,一共15列,做爲參數傳給導出指令。spa

self.exportCols = scope.exportCols;

for (let i = 0; i < table.rows.length; i ++) {
    // 獲取每行的數據
    var rowData = table.rows[i].cells;
    // 若是該列爲正常列,循環內容
    for (let j = 0; j < self.exportCols; j ++) {
        // 若是該列不存在,則賦值爲空內容
        var data = rowData[j] === undefined ? '' : rowData[j].innerHTML;
        // 拼接內容,用逗號分隔
        csvString = csvString + data + ",";
    }
    // 刪除最後多餘的逗號
    csvString = csvString.substring(0, csvString.length - 1);
    // 每行末尾添加\n進行換行
    csvString = csvString + "\n";
}

原來內層循環的是全部數據列,如今改爲傳入的有效數據列數。code

跨行表格

clipboard.png

以這個圖爲例,第一行是有15列的,可是第二行的數據只有4列,由於其他的列是第一行設置rowspan顯示的,實際上第二行的tr中只有人員資質4tdorm

clipboard.png

這就致使導出的時候第二行只有四個數據,而且是從左對齊的,因此咱們須要在跨行的列添加空數據。ip

加一個條件判斷,傳入出現被跨行的列時剩餘列的長度,用於區分是正常列仍是被跨行的列。字符串

if (self.isNormalItem(rowData)) {
    // 若是該列爲正常列,循環內容
    for (let j = 0; j < self.exportCols; j++) {
        // 若是該列不存在,則賦值爲空內容
        var data = rowData[j] === undefined ? '' : rowData[j].innerHTML;
        // 拼接內容,用逗號分隔
        csvString = csvString + data + ",";
    }
} else {
    // 根據有效數據中的跨行列拼接空數據
    for (let j = 0; j < self.multipleRowCols; j ++) {
        csvString = csvString + ",";
    }
    // 根據有效數據減去跨行列,得到非跨行列,並拼接數據
    for (let index = 0; index < self.exportCols - self.multipleRowCols; index ++) {
        csvString = csvString + rowData[index].innerHTML + ",";
    }
}

資格證出現空列

clipboard.png

由於這裏須要爲添加資格證按鈕添加一個空列,導出的時候也會出現空列,效果並很差。

clipboard.png

因此須要進行判斷,當出現被跨行的列時,須要判斷它的上一行的最後四項內容是否爲空,若是爲空,就應該把這個列的內容放到上一行。

if (self.isNormalItem(rowData)) {
    // 若是該列爲正常列,循環內容
    ...
} else if (self.isFirstItem(csvString)) {
    // 若是當前跨行資質是當前人員的第一個資質,則將該資質添加到上一行
    // 由於能添加人員資質的界面第一行的人員資質是空的,因此須要將該資
    // 質添加到上一行
    csvString = self.addDataToPreString(rowData, csvString);
} else {
    // 根據有效數據中的跨行列拼接空數據
    ...
}

再加一個else,若是當前被跨行的列是當前人員的第一我的員資質的話,就把這一行的人員資質數據添加到上一行人員資質的空白處。

下面是方法的具體實現:

// 判斷當前表格中資質是不是第一項資質
self.isFirstItem = function(string) {
    // 分隔字符串
    var csvArray = string.split(',');
    // 循環已有字符數組的倒數四個元素,判斷是否有效
    for (var i = csvArray.length - 1; i >= csvArray.length - 4; i--) {
        if (self.isValid(csvArray[i])) {
            return false;
        }
    }
    return true;
};
// 判斷當前字符是否有效
// 空字符和\n視爲無效
self.isValid = function(char) {
    if (char === '' || char === '\n') {
        return false;
    } else {
        return true;
    }
};
// 添加數據到字符串的上一行
self.addDataToPreString = function(data, string) {
    // 字符串分隔爲數據
    var csvArray = string.split(',');
    // 循環,將有效的數據添加到上一行
    for (let i = 0; i < self.validNoMultipleRowCols; i++) {
        csvArray[csvArray.length - self.validNoMultipleRowCols + i] = data[i].innerHTML;
    }
    // 數組轉換爲字符串
    return csvArray.join(',');
};

最終實現導出的csv效果:

clipboard.png

相關文章
相關標籤/搜索