H5以及Node讀取excel

支持讀寫Excel的node.js模塊

支持讀寫excel文件的模塊有不少,可是都各有憂缺點,有些僅支持xls/xlsx的一種格式,有些僅支持讀取數據,有些僅支持導出文件,有些須要依賴python解析。常見的npm依賴模塊以下:html

js-xlsx: 目前 Github 上 star 數量最多的處理 Excel 的庫,支持解析多種格式表格XLSX / XLSM / XLSB / XLS / CSV,解析採用純js實現,寫入須要依賴nodejs或者FileSaver.js實現生成寫入Excel,能夠生成子表Excel,功能強大,但上手難度稍大。不提供基礎設置Excel表格api例單元格寬度,文檔有些亂,不適合快速上手;
node-xlsx: 基於Node.js解析excel文件數據及生成excel文件,僅支持xlsx格式文件;
excel-parser: 基於Node.js解析excel文件數據,支持xls及xlsx格式文件,須要依賴python,過重不太實用;
excel-export : 基於Node.js將數據生成導出excel文件,生成文件格式爲xlsx,能夠設置單元格寬度,API容易上手,沒法生成worksheet字表,比較單一,基本功能能夠基本知足;
node-xlrd: 基於node.js從excel文件中提取數據,僅支持xls格式文件,不支持xlsx,有點過期,經常使用的都是XLSX 格式。

xlxs

對於Excel文件的內容分析轉換,已經有了比較成熟的解決方案:https://github.com/SheetJS/js...node

npm install xlsx
  • workbook 對象,指的是整份 Excel 文檔。咱們在使用 js-xlsx 讀取 Excel 文檔以後就會得到 workbook 對象。
  • worksheet 對象,指的是 Excel 文檔中的表。咱們知道一份 Excel 文檔中能夠包含不少張表,而每張表對應的就是 worksheet 對象。
  • cell 對象,指的就是 worksheet 中的單元格,一個單元格就是一個 cell 對象。
  • A1 標記,引用單元格時所使用的地址格式(如:A一、C7)
// workbook
{
 SheetNames: ['sheet1', 'sheet2'],
 Sheets: {
 // worksheet
 'sheet1': {
  // cell
  'A1': { ... },
  // cell
  'A2': { ... },
  ...
 },
 // worksheet
 'sheet2': {
  // cell
  'A1': { ... },
  // cell
  'A2': { ... },
  ...
 }
 }
}

基本用法

  1. 用 XLSX.read 讀取獲取到的 Excel 數據,返回 workbook
  2. 用 XLSX.readFile 打開 Excel 文件,返回 workbook
  3. 用 workbook.SheetNames 獲取表名
  4. 用 workbook.Sheets[xxx] 經過表名獲取表格
  5. 用 worksheet[address]操做單元格
  6. 用XLSX.utils.sheet_to_json針對單個表獲取表格數據轉換爲json格式
  7. 用XLSX.writeFile(wb, 'output.xlsx')生成新的 Excel 文件

讀取文件

import XLSX from 'xlsx';

const wb = XLSX.readFile('path/to/file.xlsx'); // 返回 workbook
workbook 對象結構以下:

{
    SheetNames: ['Sheet1', 'Sheet2'],
    Sheets: {
       'Sheet1': { ... },
       'Sheet2': { ... }
    },
    Props: { ... },
    ....
}

獲取工做表

根據表名獲取對應的工做表python

const ws = wb.Sheets[workbook.SheetNames[0]]; // 返回 worksheet
worksheet 對象結構以下:

{
    '!ref': 'A1:C7',
    A1: { ... },
    B1: { ... },
    ....
}
// 其中 worksheet['!ref'] 是工做表的有效範圍(基於 A-1)。

獲取單元格

經過 worksheet[address_of_cell] 獲取單元格,也就是經過 A1 標記的鍵名來獲取單元格:git

const cell = wb['C7'];

或者經過地址對象 { r: R, c: C } 來獲取單元格,R 和 C 分別表明從 0 開始的行和列的索引。github

// XLSX.utils 中的 encode_cell/decode_cell 方法能夠轉換單元格地址
const cell = wb[XLSX.utils.encode_cell({ r: 7, c: 2 })]; // 等同於 wb['C7']
cell 對象結構以下:

{
    v: 'C7SKY',
    w: 'C7SKY',
    t: 's',
    ....
}

編輯單元格

cell.v = '小影志';
delete cell.w;

須要注意的是,內建的導出工具會優先嚐試使用 w 的值,因此若是以後要使用導出功能,在修改值時應該同時刪除 w 按鍵或設置爲 undefined。npm

刪除行/刪除列

js-xlsx 並無提供刪除行/刪除列的功能,因此須要咱們自行實現:json

function encodeCell(r, c) {
    return XLSX.utils.encode_cell({ r, c });
}

function deleteRow(ws, index) {
    const range = XLSX.utils.decode_range(ws['!ref']);

    for (let row = index; row < range.e.r; row++) {
        for (let col = range.s.c; col <= range.e.c; col++) {
            ws[encodeCell(row, col)] = ws[encodeCell(row + 1, col)];
        }
    }

    range.e.r--;

    ws['!ref'] = XLSX.utils.encode_range(range.s, range.e);
}

function deleteCol(ws, index) {
    const range = XLSX.utils.decode_range(ws['!ref']);

    for (let col = index; col < range.e.c; col++) {
        for (let row = range.s.r; row <= range.e.r; row++) {
            ws[encodeCell(row, col)] = ws[encodeCell(row, col + 1)];
        }
    }

    range.e.c--;

    ws['!ref'] = XLSX.utils.encode_range(range.s, range.e);
}

XLSX.utils 中的 encode_range / decode_range 方法用來轉換單元格範圍(A2:C7 至關於 {s:{c:0, r:1}, e:{c:2, r:6}})。api

保存/導出

經過 XLSX.writeFile(wb, filename) 就能夠生成新的表格文件:app

XLSX.writeFile(wb, 'output.xlsx');

而 XLSX.utils.sheet_to_* 則提供了多種導出格式(csv/txt/html/json/formulae),如下是導出 JSON 文件的代碼:工具

const data = XLSX.utils.sheet_to_json(ws);

fs.writeFileSync('path/to/export.json', JSON.stringify(data, null, 4));

H5讀取excel

使用HTML5的FileReader,打開本地文件。

<input type="file" id="excel-file">
var wb;//讀取完成的數據
var rABS = false; //是否將文件讀取爲二進制字符串

function importf(obj) {//導入
                if(!obj.files) {
                    return;
                }
                var f = obj.files[0];
                var reader = new FileReader();
                reader.onload = function(e) {
                    var data = e.target.result;
                    if(rABS) {
                        wb = XLSX.read(btoa(fixdata(data)), {//手動轉化
                            type: 'base64'
                        });
                    } else {
                        wb = XLSX.read(data, {
                            type: 'binary'
                        });
                    }
                    //wb.SheetNames[0]是獲取Sheets中第一個Sheet的名字
                    //wb.Sheets[Sheet名]獲取第一個Sheet的數據
                    document.getElementById("demo").innerHTML= JSON.stringify( XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) );
                };
                if(rABS) {
                    reader.readAsArrayBuffer(f);
                } else {
                    reader.readAsBinaryString(f);
                }
}

function fixdata(data) { //文件流轉BinaryString
       var o = "",l = 0,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;
}

Node讀取excel

var fs = require('fs');
var xlsx = require('node-xlsx');
 
var list = xlsx.parse("./excel/" +"1.xlsx"); //讀取excel
 
 
var datas=[];
var data=[1,2,3];
var data1=[4,5,6];
datas.push(data);    //一行一行添加的 不是一列一列
datas.push(data1);    
writeXls(datas);
function writeXls(datas) {
    var buffer = xlsx.build([
        {
            name:'sheet1',
            data:datas   
        }
    ]);
    fs.writeFileSync('test1.xlsx',buffer,{'flag':'w'});   //生成excel
}
相關文章
相關標籤/搜索