csv和excel讀取和下載

在html5中,DOM給文件中添加了一個files集合,在選取文件中,files中包含一個File對象,每一個對象都有下列屬性:javascript

  • name: 本地文件的文件名
  • size:文件的大小
  • type: 字符串,文件的MIME類型
  • lastModifiedDate: 字符串,文件上一次被修改的時間

同時,使用FileReader對象,web應用程序能夠異步的讀取存儲在用戶計算機上的文件(或者原始數據緩衝)內容,可使用File對象或者Blob對象來指定所要處理的文件或數據。FileReader 提供了以下 幾個方法。css

  • readAsText(file,encoding):以純文本形式讀取文件,將讀取到的文本保存在 result 屬 性中。第二個參數用於指定編碼類型,是可選的。
  • readAsDataURL(file):讀取文件並將文件以數據 URI的形式保存在 result 屬性中。
  • readAsBinaryString(file):讀取文件並將一個字符串保存在 result 屬性中,字符串中的 每一個字符表示一字節。
  • readAsArrayBuffer(file):讀取文件並將一個包含文件內容的 ArrayBuffer 保存在 result 屬性中。 這些讀取文件的方法爲靈活地處理文件數據提供了極大便利。例如,能夠讀取圖像文件並將其保存 爲數據 URI,以便將其顯示給用戶,或者爲了解析方便,能夠將文件讀取爲文本形式。

先來個例子

需求:若讀取文件爲圖片,則以img展現出來,其餘狀況則以text的形式輸出。html

  1. 若要讀取文件,首先須要一個input元素
<input type="file" id="files-list">
複製代碼
  1. 接下來,若讀取的文件爲圖片,使用readAsDataURL將其轉化爲圖片,不然轉化爲text。 相應的轉化結果會保存在result中。
reader = new FileReader();
if (/image/.test(files[0].type)) {
    // 選擇文件類型爲圖片
    reader.readAsDataURL(files[0]);
    type = "image";
} else {
    // 其餘文件類型,並指定編碼類型
    reader.readAsText(files[0], 'gb2312');
    type = "text";
}

複製代碼
  1. 讀取完成後,將圖片利用img標籤展現出來;若爲text則掛載在頁面上
reader.onload = function () {
    var html = "";
    switch (type) {
        case "image":
            html = "<img src=\"" + reader.result + "\">";
            break;
        case "text":
            html = reader.result;
            console.log(html);
            break;
    }
    output.innerHTML = html;
};
複製代碼

演示連接vue

讀取圖片html5

讀取csv文件java

在利用readAsText進行讀取的時候,要指定一下編碼形式。如readAsText(files[0], 'gb2312');   
複製代碼

csv的導入

csv文件的特色: 每一行用換行符進行分隔,每一行的數據中每一項利用逗號分隔。
複製代碼

上面已經能夠將csv做爲text進行輸出了。下來繼續拿取數據。git

利用上面所說的csv的特色就能夠利用js進行循環遍歷拿到每一項的數據。github

演示連接web

其中,我將CVS中的數據轉化後,並拼在了table元素中:json

// 將讀取的數據轉化爲table
function textToCsv(data) {
    var allRows = data.split(/\n/);
    var table = '<table>';
    for (var singleRow = 0; singleRow < allRows.length - 1; singleRow++) {
        if (singleRow === 0) {
            table += '<thead>';
            table += '<tr>';
        } else {
            table += '<tr>';
        }
        var rowCells = allRows[singleRow].split(',');
        for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
            if (singleRow === 0) {
                // 表格的標題
                table += '<th>';
                table += rowCells[rowCell];
                table += '</th>';
            } else {
                // 表格內容
                table += '<td>';
                table += rowCells[rowCell];
                table += '</td>';
            }
        }
        if (singleRow === 0) {
            table += '</tr>';
            table += '</thead>';
            table += '<tbody>';
        } else {
            table += '</tr>';
        }
    }
    table += '</tbody>';
    table += '</table>';
    console.log(table);
    document.getElementById('table').innerHTML = table;
}
複製代碼

效果圖以下:

既然都讀取出來,下載?

關於下載的操做,能夠藉助於a標籤。先介紹下相關的屬性:

  • download: 用於指定下載的文件名
  • href:爲所要下載的文件的連接(需爲本地連接)

上一個列子的下載就是用的上面的作法:

<a href="./file/會員.csv" download="demo.csv">下載測試文件</a>
複製代碼

先準備數據 csv文件的頭部數據:

var head = [
    ['姓名(最多10個字)', '手機號(必填)', '等級', '生日(好比:1989/08/08 或 1989-08-08)', '積分(限整數)']
];
複製代碼

csv文件的主體數據:

var people = [{
    "name": "吳三桂",
    "phone": "18709237410",
    "level": "黃金",
    "birthday": "1989/8/5",
    "points": "100"
}, {
    "name": "史泰龍",
    "phone": "18709237401",
    "level": "青銅2",
    "birthday": "1993/9/6",
    "points": "300"
}, {
    "name": "阿超",
    "phone": "18883920287",
    "level": "白金",
    "birthday": "1993/9/3",
    "points": "500"
}];
複製代碼

下來就是數據的格式轉換:

//. 將數據push到大數組中 
var p = people;
for (var i = 0; i < p.length; i++) {
    head.push([p[i].name, p[i].phone, p[i].level, p[i].birthday, p[i].points]);
}
// 按照csv文件內容格式,把每一個數組用 , 鏈接,造成一行,並存入新數組 
var csvRows = [];
for (var j = 0; j < head.length; j++) {
    csvRows.push(head[j].join(','))
}
//s4. 把新數組用 \n 回車鏈接 
var csvString = csvRows.join('\n'); 
複製代碼

最後實現下載:

//利用a標籤實現下載
function saveAs(obj, fileName) { 
    var tmpa = document.createElement("a");
    tmpa.download = fileName || "下載.csv";
    tmpa.href ='data:attachment/csv,' + encodeURI(obj); //綁定a標籤
    tmpa.click(); //模擬點擊實現下載
    setTimeout(function () { //延時釋放
        URL.revokeObjectURL(obj); //用URL.revokeObjectURL()來釋放這個object URL
    }, 100);
}
複製代碼

演示連接
效果圖

另外, 將json文件轉化爲csv格式能夠利用 json2csv

下面將使用js-xlsx對csv文件進行操做:

excel文件讀取

xlsx相關api:

  • XLSX.utils.sheet_to_json方法解析表格對象返回相應的JSON數據
  • XLSX.read()以二進制流方式讀取excel數據

在JavaScript中,有2個函數分別用來處理解碼和編碼base64 字符串:

  • atob() 函數可以解碼經過base-64編碼的字符串數據。
  • btoa() 函數可以從二進制數據「字符串」建立一個base-64編碼的ASCII字符串。

步驟:

  1. readAsArrayBuffer能夠將讀取的數據轉化爲二進制數據;
  2. 經過btoa()將數據轉化爲base64格式;
  3. 而後結合XLSX.utils.sheet_to_json轉化爲json
var wb;//讀取完成的數據
 //導入
function importf(obj) {
    if (!obj.files) {
        return;
    }
    var f = obj.files[0];
    var reader = new FileReader();
    reader.readAsArrayBuffer(f);
    reader.onload = function (e) {
        var data = e.target.result;
        var wb =XLSX.read(btoa(fixedData(data)), { type: 'base64' });//將數據轉化爲二進制
        //wb.SheetNames[0]是獲取Sheets中第一個Sheet的名字
        //wb.Sheets[Sheet名]獲取第一個Sheet的數據
        document.getElementById("excel").innerHTML = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
    };

}
複製代碼
//文件流轉BinaryString
function fixedData(data) {
    let o = ''
    let l = 0
    const w = 10240
    for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w,
        l * w + w)))
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
    return o
}
複製代碼

效果圖預覽:

查看演示

附上一個vue-element-admin關於Excel文件讀取的源碼: 查看連接

Excel文件導出

這裏依然會用到js-xlsx, 文件下載採用FileSaver.js

<button onclick="downloadExl(people)">導出</button>
複製代碼
  1. 數據準備
var people = [{
    "name": "吳三桂",
    "phone": "18709237410",
    "level": "黃金",
    "birthday": "1989/8/5",
    "points": "100"
}, {
    "name": "史泰龍",
    "phone": "18709237401",
    "level": "青銅2",
    "birthday": "1993/9/6",
    "points": "300"
}, {
    "name": "阿超",
    "phone": "18883920287",
    "level": "白金",
    "birthday": "1993/9/3",
    "points": "500"
}];
複製代碼

下來定義一個wb保存導出數據

var wb = {
  SheetNames: ["Sheet1"],   //標題名
  Sheets: { }               //保存表內的數據
}
複製代碼
  1. XLSX.utils.json_to_sheet(people):能夠將json對象轉化爲工做表;將轉化的結果賦值非 wb.Sheets['Sheet1']

!ref: 表示表格輸出的範圍
A1-Zx: 這些就對應的是Excel中單元格的位置;

其中:Sheet1相關參數介紹:

鍵名
v 原始值
t b布爾值,e錯誤,n數字,d日期,s文本

更多屬性請參照: 官方文檔

  1. 指定導出格式,這裏採用xlsx格式
const wopts = { bookType: 'xlsx', bookSST: false,type: 'binary' };
//這裏的數據是用來定義導出的格式類型
// const wopts = { bookType: 'csv', bookSST: false, type: 'binary' };//ods格式
// const wopts = { bookType: 'ods', bookSST: false, type: 'binary' };//ods格式
// const wopts = { bookType: 'xlsb', bookSST: false, type: 'binary' };//xlsb格式
// const wopts = { bookType: 'fods', bookSST: false, type: 'binary' };//fods格式
// const wopts = { bookType: 'biff2', bookSST: false, type: 'binary' };//xls格式
複製代碼
  1. 設置表頭 將工做表的A1-Z1等替換稱爲中文
// 將指定的天然數轉換爲26進製表示。映射關係:[0-25] -> [A-Z]。
function getCharCol(n) {
    var temCol = '',
        s = '',
        m = 0
    while (n >= 0) {
        m = n % 26 + 1
        s = String.fromCharCode(m + 64) + s
        n = (n - m) / 26
    }
    return s
};
["ID","手機號","等級" ,"生日","積分"].forEach((v,i)=>{data[getCharCol(i)+1] = { t: "s", v: v ,w:v};})
複製代碼
  1. 下載保存,

利用XLSX.write(wb, wopts);
wb: 二進制數據流
wopts: 指定的導出格式等信息

下載保存此次不採用a標籤的方式。採用FileSaver.js

saveAs(new Blob([s2ab(XLSX.write(wb, wopts))], {type: "application/octet-stream"}), "js-xlsx文件下載實例" + '.' + wopts.bookType);
複製代碼

查看演示

新人首次發帖,,你們勿噴!!!

github

參考文章:

  1. 理解DOMString、Document、FormData、Blob、File、ArrayBuffer數據類型--張鑫旭
  2. 文件和二進制數據的操做--阮一峯
相關文章
相關標籤/搜索