nodejs操作excel并配合edatagrid使用

nodejs读取文件夹下子文件(夹)名称:

/**
 * 查询tmp文件夹下子文件夹名称
 */
router.post("/tmpList", function (req, res) {
    fs.readdir("./public/tmp", function (err, files) {
        var jsonArray = new Array();                             //[{id:0,name:'陕西省'},{id:1,name:'福建省'},{id:2,name:'陕西省'}]
        jsonArray.push({id: "", name: '请选择省或地区'});
        for (var index in files) {
            var jsonObj = {};
            jsonObj.id = index;
            jsonObj.name = files[index];
            jsonArray.push(jsonObj);
        }
        res.send(jsonArray);
    });
});

读取之后渲染显示:

<input style="width: 150px;" class="easyui-combobox" id="province" name="province" data-options="valueField:'id',textField:'name',url:'/market/tmpList',panelHeight:'300px;',editable:false">

使用node-xlsx加载、生成excel文件(后缀名为.xlsx):

var xlsx = require("node-xlsx");
var path = require('path');
var url = path.join(__dirname + "/" + req.body.url);
var obj = xlsx.parse(url);
var data = obj[0].data;

其中,url为*.xlsx文件路径,data为读取的excel数据(data[0]为excel表头数据,为一个数组,data[i]分别为第i+1行数据,也是一个数组),使用如下生成一个excel文件:

var fs = require("fs");
var xlsx = require("node-xlsx");
var path = require('path');
var file = xlsx.build([{name: "Sheet1", data: dataArray}]);
fs.writeFileSync(__dirname + "/" + url, file, "binary");

其中,url同样为*.xlsx路径(含后缀名),dataArray的格式为:

[ [ '姓名', '性别', '学号', '年龄', '电话', '地址', '是否党员' ],[ '张三', '男', '000', '13' ],[ '李四', '男', '001', '14' ] ]

其中,[ '姓名', '性别', '学号', '年龄', '电话', '地址', '是否党员' ] 为生成的excel表头,其余为对应的内容(注意:内容数量和表头数不匹配时,空缺默认留空)。

页面效果:

依次选择各个区域后,单击“加载模板”即可读取excel数据显示,读取的excel内容如下:

可以看出是完全读取的excel内容显示,页面部分实现:

<table id="dg" title="行情模板" idField="id" style="width:100%;position: absolute;top: 50px;bottom: 0px;overflow-x: hidden"
       toolbar="#toolbar" idField="id" rownumbers="true" fitColumns="true" singleSelect="true" >
</table>
<div id="toolbar">
    <div style="margin-top: 10px;margin-bottom: 3px;margin-left: 2px;font-size: 14px;">请选择要修改的行情模板:</div>
    <div style="float: left;margin-top: 10px;margin-left: 2px;">
        商品区域:<input style="width: 150px;" class="easyui-combobox" id="province" name="province"
                    data-options="valueField:'id',textField:'name',url:'/tmpList',panelHeight:'300px;',editable:false">
        <input style="width: 150px;" class="easyui-combobox" id="city" name="city"
               data-options="valueField:'id',textField:'name',panelHeight:'auto',editable:false">
    </div>
    <div style="float: left;margin-top: 10px;margin-left: 5px;">
        商品大类:<input class="easyui-combobox" id="bigType"
                    data-options="textField:'name',valueField:'id',url:'',panelHeight:'auto',editable:false"
                    style="width: 150px;"/>
    </div>
    <div style="margin-top: 10px;float: left;margin-left: 5px;">
        品种:<input class="easyui-combobox" id="variety"
                  data-options="textField:'name',valueField:'id',url:'',panelHeight:'auto',editable:false"
                  style="width: 150px;"/>
    </div>
    <input type="hidden" id="headData"/>
    <a class="easyui-linkbutton" plain="true" iconCls="icon-2012080412111" style="margin-top: 8px;margin-left: 5px;" href="javascript:void(0)" onclick="javascript:loadTemplet()">加载模板</a>
    <div style="clear: both">&nbsp;</div>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true"
       onclick="javascript:add()">添加</a>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true"
       onclick="javascript:del()">删除</a>
    <!--<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true"-->
       <!--onclick="javascript:update()">修改</a>-->
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-save" plain="true"
       onclick="javascript:save()">保存</a>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-undo" plain="true"
       onclick="javascript:cancel()">撤销</a>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-arrow_up" plain="true"
       onclick="javascript:moveUp()">上移</a>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-arrow_down" plain="true"
       onclick="javascript:moveDown()">下移</a>
</div>

主要js代码实现:

<script type="text/javascript">
        var editFlag = undefined;//设置一个编辑标记
        var url = null;
        jQuery(function () {
            jQuery("#dg").edatagrid({});
            jQuery("#variety").combobox({
                onSelect: function (record) {
                    var proName = jQuery("#province").combobox("getText");
                    var cityName = jQuery("#city").combobox("getText");
                    var bigTypeName = jQuery("#bigType").combobox("getText");
                    var varietyName = jQuery("#variety").combobox("getText");
                    if (varietyName == "请选择品种") {
                        jQuery.messager.show({title: "提示", msg: "请先选择价格行情区域"});
                        return;
                    }
                    url = "../public/tmp/" + proName + "/" + cityName + "/" + bigTypeName + "/" + varietyName + "/" + varietyName + ".xlsx";
                    jQuery.post("/tmpHead",{
                        url:url
                    },function(result){
                        jQuery("#headData").val(result.data);
                    });
                }
            });
        });
        function add(){
//            if(jQuery("#dg").edatagrid("getRows") == null || jQuery("#dg").edatagrid("getRows") == ""){
//                jQuery.messager.show({title:"提示",msg:"请先加载模板"});
//                return;
//            }
            jQuery("#dg").edatagrid("addRow");
        }
        function cancel(){
            jQuery("#dg").edatagrid("rejectChanges");
            jQuery("#dg").edatagrid("unselectAll");
            editFlag = undefined;
        }
        function del(){
            if(jQuery("#dg").edatagrid("getRows") == null || jQuery("#dg").edatagrid("getRows") == ""){
                jQuery.messager.show({title:"提示",msg:"请先加载模板"});
                return;
            }
            var rowIndex = editFlag;            //要删除的行索引
            if(!rowIndex){
                jQuery.messager.show({title:"提升",content:"请先选择要删除的行"});
                return;
            }
            jQuery.messager.confirm("提示","确定删除?",function(r){
                if(r){
                    jQuery('#dg').edatagrid('deleteRow', rowIndex);
                    var data = JSON.stringify(jQuery('#dg').edatagrid("getRows"));     //获取删除后的数据,后台重新生成Excel
                    jQuery.post("/tmpSave",{
                        data:data,
                        url:url,
                        headData:jQuery("#headData").val()
                    },function(result){
                        jQuery.messager.show({title:"提示",msg:"删除成功!"});
                    });
                }
            })
        }
        function save(){
            if(jQuery("#dg").edatagrid("getRows") == null || jQuery("#dg").edatagrid("getRows") == ""){
                jQuery.messager.show({title:"提示",msg:"请先加载模板"});
                return;
            }
       for(var j = 0; j < jQuery("#dg").edatagrid("getRows").length; j++){    //循环校验
                if(!jQuery('#dg').edatagrid('validateRow',j)){
                    jQuery.messager.show({title:"提示",msg:"输入内容要求20字符以内且不能为空!"});
                    return;
                }
            }   
            jQuery('#dg').edatagrid("acceptChanges");     //获取删除后的数据,后台重新生成Excel
            var data = JSON.stringify(jQuery('#dg').edatagrid("getRows"));
            jQuery.post("/tmpSave",{
                data:data,
                url:url,
                headData:jQuery("#headData").val()
            },function(result){
                jQuery('#dg').edatagrid("reload");
                jQuery.messager.show({title:"提示",msg:"保存成功!"});
            });
        }
        function moveUp() {
            var row = jQuery("#dg").edatagrid('getSelected');
            var index = jQuery("#dg").edatagrid('getRowIndex', row);
            mysort(index, 'up', 'dg');
        }
        function moveDown(){
            var row = jQuery("#dg").datagrid('getSelected');
            var index = jQuery("#dg").datagrid('getRowIndex', row);
            mysort(index, 'down', 'dg');
        }
        function mysort(index, type, gridname) {
            if ("up" == type) {
                if (index != 0) {
                    var toup = jQuery('#' + gridname).edatagrid('getData').rows[index];
                    var todown = jQuery('#' + gridname).edatagrid('getData').rows[index - 1];
                    jQuery('#' + gridname).edatagrid('getData').rows[index] = todown;
                    jQuery('#' + gridname).edatagrid('getData').rows[index - 1] = toup;
                    jQuery('#' + gridname).edatagrid('refreshRow', index);
                    jQuery('#' + gridname).edatagrid('refreshRow', index - 1);
                    jQuery('#' + gridname).edatagrid('selectRow', index - 1);
                }
            } else if ("down" == type) {
                var rows = jQuery('#' + gridname).edatagrid('getRows').length;
                if (index != rows - 1) {
                    var todown = $('#' + gridname).edatagrid('getData').rows[index];
                    var toup = $('#' + gridname).edatagrid('getData').rows[index + 1];
                    jQuery('#' + gridname).edatagrid('getData').rows[index + 1] = todown;
                    jQuery('#' + gridname).edatagrid('getData').rows[index] = toup;
                    jQuery('#' + gridname).edatagrid('refreshRow', index);
                    jQuery('#' + gridname).edatagrid('refreshRow', index + 1);
                    jQuery('#' + gridname).edatagrid('selectRow', index + 1);
                }
            }
        }
        function loadTemplet(){
            var proName = jQuery("#province").combobox("getText");
            var cityName = jQuery("#city").combobox("getText");
            var bigTypeName = jQuery("#bigType").combobox("getText");
            var varietyName = jQuery("#variety").combobox("getText");
            if (varietyName == "请选择品种") {
                jQuery.messager.show({title: "提示", msg: "请先选择要加载的模板"});
                return;
            }
            var url = "../public/tmp/" + proName + "/" + cityName + "/" + bigTypeName + "/" + varietyName + "/" + varietyName + ".xlsx";
            var headData = jQuery("#headData").val().split(",");
            jQuery("#dg").edatagrid({
                url:"/tmpShow",
                nowrap: true,
                loadMsg : "正在努力为您加载数据",
                columns: [[
                    {
                        field: 'trade', title: headData[0], width: "15%", align: 'center', editor: {
                        type: 'text',
                        options: {
                            required: true
                        }
                    }
                    },
                    {
                        field: 'standard', title: headData[1], width: "15%", align: 'center', editor: {
                        type: 'text',
                        options: {
                            required: true
                        }
                    }
                    },
                    {
                        field: 'material', title: headData[2], width: "15%", align: 'center', editor: {
                        type: 'text',
                        options: {
                            required: true
                        }
                    }
                    },
                    {
                        field: 'steelFactory', title: headData[3], width: "15%", align: 'center', editor: {
                        type: 'text',
                        options: {
                            required: true
                        }
                    }
                    },
                    {
                        field: 'price', title: headData[4], width: "10%", align: 'center'
                    },
                    {
                        field: 'change', title: headData[5], width: "15%", align: 'center'
                    },
                    {
                        field: 'remark', title: headData[6], width: "15%", align: 'center'
                    }
                ]],
                onBeforeLoad: function (param) {
                    param.url = url;
                },
                onAfterEdit : function(rowIndex, rowData, changes) {
                    editFlag = undefined;//重置
                    jQuery("#dg").edatagrid("unselectAll");
                },
                onDblClickCell : function(rowIndex, field, value) {//双击该行修改内容
                    if (editFlag != undefined) {
                        jQuery("#dg").edatagrid('endEdit', editFlag);//结束编辑,传入之前编辑的行
                        jQuery("#dg").edatagrid('beginEdit', rowIndex);//开启编辑并传入要编辑的行
                        editFlag = rowIndex;
                    }
                    if (editFlag == undefined) {
                        jQuery("#dg").edatagrid('beginEdit', rowIndex);//开启编辑并传入要编辑的行
                        editFlag = rowIndex;
                    }
                },
                onClickCell : function(rowIndex, field, value) {//双击该行修改内容
                    editFlag = rowIndex;
                }
            });
        }
    </script>

可以直接进行修改、保存、撤销、新增以及上移、下移操作,保存后,数据直接提交至后台直接重新生成excel文件。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

从零开始学 Web 之 移动Web(三)Zepto

Zepto是一个轻量级的针对现代高级浏览器的 JavaScript库, 它与jquery有着类似的api。

1022
来自专栏繁花云

liunx下利用某软件创建图形伪界面

Liunx下的dialog是一个可以创建对话框的工具,每个对话框提供的输出有两种形式:1、将所有输出到stderr,不显示到屏幕;2、使用退出状态码,OK为0...

690
来自专栏理论坞

那些你不知道的Photoshop冷知识⑤——CC2015评测专题

笔者在探索新版本时,首先注意的便是首选项的变化,可以发现这次更新之后首选项侧边栏多了不少东西,点进去之后才发现原来是进行了重新分类,那么有哪些好玩的功能呢?介绍...

744
来自专栏Django Scrapy

Django安装及简单使用1.5

Django安装及简单使用1.5 代码都在github: URL:https://github.com/njxshr/codes/tree/master/t...

3147
来自专栏deepcc

学习js在线html(富文本)编辑器

8657
来自专栏用户2442861的专栏

chrome调试工具常用功能整理

chrome devtools 中 Elements panel 是审查 dom 元素和 css 的, 可以实时修改 dom/css.

691
来自专栏小筱月

多选穿梭框总结 (vue + element)

1053
来自专栏Java成神之路

GEF入门实例_总结_03_显示菜单和工具栏

还记得上一节我们新建的类: ApplicationActionBarAdvisor 吗,这个类继承自 ActionBarAdvisor。

882
来自专栏程序员的诗和远方

TypeScript 中使用 CSS Modules

CSS 的全局性 相当长一段时间 CSS 总是在页面上作为一个全局的存在,以前这个『特性』影响还不算很大,命名上注意一点,比如使用 BEM 也能一定程度上解决问...

3537
来自专栏我的博客

Dedecms普通模型入门教程

1. 默认模板设置 里面是default后面变量名字是cfg_df_style(在模版中使用方法是{dede:golbal.cfg_df_style/}获取的路...

3536

扫码关注云+社区