用的是koa2框架,但好好處理一下,用express框架也是可以的。導出的Excel是xlsx的格式,解析導入Excel的有xlsx和csv格式。通常導入Excel是要上傳的,然后獲取文件的路徑,這里省略。強烈不建議導入的Excel直接保存到數據庫,建議將數據發到頁面上確認沒問題,再保存,防止導入垃圾數據。導入的Excel里也不要什么樣式,防止不符合解析規范。建議用xlsx格式的Excel導入,解析比較簡單。
最后用Buffer導出Excel輸出,參考了:https://blog.csdn.net/zhangfei8625/article/details/51802166
我的Excel內容

index.html 的代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Excel的導入導出</title> <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"> </script> </head> <body> <hr/> 導出Excel:<button id="exportexcel">提交</button> <hr/> 導入xlsx格式:<button id="importexcelxlsx">提交</button> <hr/> 導入csv格式:<button id="importexcecsv">提交</button> <script> $(function () { $("#exportexcel").on("click",function () { window.open("/exportexcel") }); $("#importexcelxlsx").on("click",function () { $.ajax({ url : "/importexcelxlsx", type : "POST", data : {}, success : function(data){ console.log(data); } }); }); $("#importexcecsv").on("click",function () { $.ajax({ url : "/importexcelcsv", type : "POST", data : {}, success : function(data){ console.log(data); } }); }); }) </script> </body> </html>
app.js 的代碼
const Koa = require("koa");
const router = require("koa-router")();
const fs=require("fs");
const nodeExcel = require('excel-export');
const csv=require('csv');
const dict = require('gbk-dict').init();//調用gbk-dict中的init這個方法
const xlsx = require('node-xlsx');
const app = new Koa();
app.use(router.routes());
router.get("/",(ctx)=>{
ctx.body = fs.readFileSync("./index.html","utf-8");
});
//導出Excel,xlsx格式
router.get('/exportexcel',async (ctx) => {
async function readydata() {
//做點什么,如從數據庫取數據
let exceldata=[
{name:"張三",age:"20",sex:"男",birthday:"1998-10-10"},
{name:"李四",age:"21",sex:"男",birthday:"1997-08-08"},
{name:"王五",age:"22",sex:"男",birthday:"1996-06-06"},
{name:"趙六",age:"20",sex:"男",birthday:"1998-12-12"},
];
return exceldata;
}
//導出
async function exportdata(v) {
let conf ={};
conf.name = "mysheet";//表格名
let alldata = new Array();
for(let i = 0;i<v.length;i++){
let arr = new Array();
arr.push(v[i].name);
arr.push(v[i].age);
arr.push(v[i].sex);
arr.push(v[i].birthday);
alldata.push(arr);
}
//決定列名和類型
conf.cols = [{
caption:'姓名',
type:'string'
},{
caption:'年齡',
type:'number'
},{
caption:'性別',
type:'string'
},{
caption:'出生日期',
type:'string',
//width:280
}];
conf.rows = alldata;//填充數據
let result = nodeExcel.execute(conf);
//最后3行express框架是這樣寫
// res.setHeader('Content-Type', 'application/vnd.openxmlformats');
// res.setHeader("Content-Disposition", "attachment; filename=" + "Report.xlsx");
// res.end(result, 'binary');
let data = new Buffer(result,'binary');
ctx.set('Content-Type', 'application/vnd.openxmlformats');
ctx.set("Content-Disposition", "attachment; filename=" + "Report.xlsx");
ctx.body=data;
}
let r=await readydata();
r=await exportdata(r);
});
//導入Excel,xlsx格式
const xlsxfile="E:/xlsx格式.xlsx";
router.post('/importexcelxlsx',async (ctx) => {
async function analysisdata() {
return new Promise((resolve,reject)=>{
//解析xlsx
let obj = xlsx.parse(xlsxfile);
resolve(obj);
});
}
async function readdata(v) {
console.log("xlsx =" ,v);//xlsx = [ { name: 'Sheet1', data: [ [Array], [Array], [Array] ] } ]
console.log("數據 = ",v[0]);//數據 = { name: 'Sheet1',
// data: [ [ '姓名', '年齡' ], [ '張三', 20 ], [ '李四', 30 ] ]}
console.log("要上傳的數據 = ",v[0].data);//要上傳的數據 = [ [ '姓名', '年齡' ], [ '張三', 20 ], [ '李四', 30 ] ]
ctx.body=v;
}
let r=await analysisdata();
r=await readdata(r);
});
//導入Excel,csv格式
const csvfile="E:/csv格式.csv";
router.post('/importexcelcsv',async (ctx) => {
async function analysisdata() {
return new Promise((resolve,reject)=>{
//解析csv
let output = new Array();//創建數組
let parser = csv.parse({delimiter: ','});//調用csv模塊的parse方法
let input = fs.createReadStream(csvfile);//調用fs模塊的createReadStream方法
input.on("data",function(data){
parser.write(dict.gbkToUTF8(data));
});
input.on("close",function(){
parser.end();
});//讀取操作的緩存裝不下,只能分成幾次發送,每次發送會觸發一個data事件,發送結束會觸發end事件
parser.on('readable',function(){
while(record = parser.read()){
output.push(record);
}
});
parser.on('finish',function() {
resolve(output); ;
//output是整個數據的數組
})
});
}
async function readdata(v) {
console.log("csv =" ,v);//csv = [ [ '姓名', '年齡' ], [ '張三', '20' ], [ '李四', '30' ] ]
ctx.body=v;
}
let r=await analysisdata();
r=await readdata(r);
});
app.listen(3000);
console.log("listen on 3000");
導出的Excel

