nodejs:导出Excel和解析导入的Excel

用的是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

 

posted @ 2018-06-01 13:11  赤羽飞鸿  阅读(30397)  评论(0编辑  收藏  举报