Node.js和xlsjs或exceljs

7
2个回答

12

两种方式都可以实现,不过我建议使用exceljs,因为它更易于使用。可以参考以下示例代码:

    var Excel = require("exceljs");
    var workbook = new Excel.Workbook();
    workbook.xlsx.readFile(templatePath)
        .then(function() {
            worksheet = workbook.getWorksheet(1);
            worksheet.addRow([3, "Sam", new Date()]);
            workbook.xlsx.writeFile(path)
                .then(function(){
                    helper.openFile(path);
                });
        });

3

以下是xlsjs和csv的代码:

app.component.html

<!--The content below is only a placeholder and can be replaced.-->

<h2>Export as Excel</h2>
<button (click)="SortExcel()">Sort And Download</button><br><br>
<button (click)="GroupExcel()">Group And Download</button>

<h2>Export as CSV</h2>
<button (click)="SortCSV()">Sort And Download</button><br><br>
<button (click)="GroupCSV()">Group And Download</button>

app.component.spec.ts
-------------------------
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'reports'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('reports');
  });

  it('should render title in a h1 tag', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to reports!');
  });
});

app.component.ts
--------------------------
import { Component } from '@angular/core';
import { ExcelService } from './excel.service';
import { CSVService } from './csv.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {


  constructor(public excelservice : ExcelService, public csvservice : CSVService) {

  }

    SortExcel() {
      this.excelservice.sortby = "Name";
      this.excelservice.SortAndDownload(0);      
    }


    GroupExcel() {
      this.excelservice.groupby = "Bank";
      this.excelservice.GroupAndDownload();
    }


    SortCSV() {
      this.csvservice.sortby = "Bank";
      this.csvservice.SortAndDownload();
    }


    GroupCSV() {
      this.csvservice.groupby = "Bank";
      this.csvservice.GroupAndDownload();
    }
}

csv.service.ts
---------------------
import { Injectable } from '@angular/core';
import * as FileSaver from 'file-saver';

@Injectable({
  providedIn: 'root'
})
export class CSVService {

  sortby: string;
  groupby: string;
  testdata = [
    { Name: "ABCD", Bank: "CS", AccountType: "Corporate" },
    { Name: "PQRS", Bank: "SBI", AccountType: "Corporate" },
    { Name: "MNOP", Bank: "J,P", AccountType: "Corporate" },
    { Name: "JKLM", Bank: "CS", AccountType: "Individual" },
    { Name: "XYZ", Bank: "CS", AccountType: "Corporate" },
    { Name: "Dan", Bank: "CS", AccountType: "Individual" }
  ];

  constructor() { }

  SortAndDownload() {
    console.log("Start Time " + new Date());
    var csv = "";
    var filename = 'export.csv';
    csv += this.getHeader(this.testdata);
    this.testdata.sort(this.compare.bind(this));
    csv += this.getrows(this.testdata) + "\n";

    this.exportFile(csv, filename);
    console.log("End Time " + new Date());
  }






  private exportFile(data: string, filename: string) {
    var BOM = "\uFEFF";
    const blob = new Blob([BOM + data], { type: 'text/csv;charset=utf-8' });
    FileSaver.saveAs(blob, filename);
  }



  private compare(a, b) {
    if (a[this.sortby] < b[this.sortby])
      return -1;
    if (a[this.sortby] > b[this.sortby])
      return 1;
    return 0;
  }



  ///////Get the List of Attributes from Data
  private getHeader(data) {
    if (data == null || !data.length) {
      return null;
    }

    let columnDelimiter = ',';
    let lineDelimiter = '\n';

    let keys = Object.keys(data[0]);
    for (var i = 0; i < keys.length; i++) {
      if (keys[i].indexOf('"') != -1) {
        keys[i] = keys[i].replace(/"/g, '""');
      }
    }
    let result = '';

    result += '"';
    for (var i = 0; i < keys.length; i++) {
      if (i > 0) result += columnDelimiter;
      result += "'" + keys[i] + "'";
    }
    result += '"';

    result += lineDelimiter;
    return result;
  }





  GroupAndDownload() {
    var csv = "";
    var filename = 'export.csv';
    csv += this.getHeader(this.testdata);
    csv += this.group_by(this.testdata);
    this.exportFile(csv, filename);

  }




  //////Convert All Object Specified in Array into CSV Format
  private getrows(data) {
    if (data == null || !data.length) {
      return null;
    }
    let columnDelimiter = ',';
    let lineDelimiter = '\n';

    let keys = Object.keys(data[0]);
    let result = '';

    data.forEach(function (item) {
      let ctr = 0;
      result += '"';
      keys.forEach(function (key) {
        if (ctr > 0) result += columnDelimiter;

        if (item[key] != undefined && item[key].indexOf('"') != -1) {
          item[key] = item[key].replace(/"/g, '""');
        }
        result += "'" + item[key] + "'";
        ctr++;
      });
      result += '"';
      result += lineDelimiter;
    });

    return result;
  }




  /////Return CSV Data Grouped By Specified Attribute
  private group_by(data) {

    let set = new Set();
    var items = [];
    var itr = 0;
    var res = "";

    data.forEach(function (item) {
      set.add(item[this.groupby]);
    }.bind(this));

    set.forEach(function (val1) {
      var temp = [];
      var cnt = 0;

      data.forEach(function (item) {
        if (item[this.groupby] === val1) {
          temp[cnt] = item;
          cnt++;
        }
      }.bind(this));

      items[itr] = temp;
      itr++;
    }.bind(this));

    itr = 0;
    var tem1 = this;
    set.forEach(function (val1) {
      if (val1.indexOf('"') != -1) {
        val1 = val1.replace(/"/g, '""');
      }
      res += "\"'" + val1 + "'\"\n";
      var tmp = items[itr];
      console.log(tmp);
      // res += this.getrows(items[itr++]);
      res += tem1.getrows(tmp);
      itr++;

    }.bind(this));
    return res;
  }

}

excel.service.ts
-----------------------------
import { Injectable } from '@angular/core';
import * as FileSaver from 'file-saver';
import * as XLSX from 'xlsx';


const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
const EXCEL_EXTENSION = '.xlsx';


@Injectable({
  providedIn: 'root'
})
export class ExcelService {

  sortby: string;
  groupby: string;
  testdata = [
    { Name: "ABCD", Bank: "CS", AccountType: "Corporate", Balance:5000 },
    { Name: "PQRS", Bank: "SBI", AccountType: "Corporate", Balance:2000 },
    { Name: "MNOP", Bank: "J,P", AccountType: "Corporate", Balance:9956 },
    { Name: "JKLM", Bank: "CS", AccountType: "Individual", Balance:4521 },
    { Name: "XYZ", Bank: "CS", AccountType: "Corporate", Balance:45201 },
    { Name: "Dan", Bank: "CS", AccountType: "Individual", Balance:10023 }
  ];

  constructor() { }


  GroupAndDownload() {
    var csv;
    var filename = 'export.csv';
    let data = this.GroupBy();
    this.exportFile(data,filename);
  }



  private GroupBy() {
    let res=[];
    let set = new Set();
    let map = new Map();
    var key = Object.keys(this.testdata[0])[0];

    this.testdata.forEach(function (item) {
      set.add(item[this.groupby]);
    }.bind(this));

    this.testdata.forEach(function (item) {
      let key = item[this.groupby];
      if(map.has(key)) {
        map.get(key).push(item);
      } else {
        let arr = [];
        arr.push(item);
        map.set(key,arr);
      }
    }.bind(this));

    set.forEach(function (val) {
      let header={};
      header[key] = val;
      res.push(header);  
      res = res.concat(map.get(val))
    });
    return res;
  }




  SortAndDownload(ascending) {
    var csv = "";
    var filename = 'export';
    var data = this.testdata;
    if(ascending==0) {
      data.sort(this.compare.bind(this));
    } else if(ascending==1) {
      data.sort(this.compare1.bind(this));
    }

    this.exportFile(data, filename);
  }


  ////Comparator for Ascending Order
  private compare(a, b) {
    if (a[this.sortby] < b[this.sortby])
      return -1;
    if (a[this.sortby] > b[this.sortby])
      return 1;
    return 0;
  }



  ////Comparator for Descending Order
  private compare1(a, b) {
    if (a[this.sortby] > b[this.sortby])
      return -1;
    if (a[this.sortby] < b[this.sortby])
      return 1;
    return 0;
  }


  private exportFile(data:any[], filename:string) {
    const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data);
    const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
    const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });

    const blobdata: Blob = new Blob([excelBuffer], {
      type: EXCEL_TYPE
    });
    FileSaver.saveAs(blobdata, filename + EXCEL_EXTENSION);

  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接