惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
WordPress大学
WordPress大学
C
Check Point Blog
GbyAI
GbyAI
U
Unit 42
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
Blog — PlanetScale
Blog — PlanetScale
J
Java Code Geeks
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Hugging Face - Blog
Hugging Face - Blog
Vercel News
Vercel News
博客园 - 【当耐特】
美团技术团队
小众软件
小众软件
S
SegmentFault 最新的问题
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Cloudflare Blog
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog

博客园 - Charleston

配置Windows 2008 R2 防火墙允许远程访问SQL Server 2008 R2 heroku空间部署步骤 网站部署后Parser Error Message: Could not load type 的解决方案 C#中准确跟踪错误异常所在的文件位置方法 *(转)超时时间已到。超时时间已到 但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用 并且达到了最大池大小。 情感分析资源 (转) 布朗语料库中条件概率分布函数ConditionalFreqDist使用 一些常用的NLTK频率分布类中定义的函数 修改tt模板让ADO.NET C# POCO Entity Generator With WCF Support 生成的实体类继承自定义基类 利用ELMAH和Sqlite快速完成错误日志的捕获和存储 DbHelperSQL和Dapper数据访问的性能对比 Guide to Data Mining 读书笔记 相似度距离算法的取舍 情感分析面临的挑战 Ulipad中设置自定义模块(module)路径的方法(图) GAE的for application does not match expression '^(?:[a-z\d\-]{1,100}\~)?(?:(?!\-)[a-z\d 错误 - Charleston 利用HttpHandler和Jquery进行数据库增改删查操作 机器学习算法相关的开源架构介绍 JSON C# Class Generator ---由json字符串生成C#实体类的工具 Win7下附加sql2005数据库失败 错误代码5120的解决方法
利用Aspose.Cells完成easyUI中DataGrid数据的Excel导出功能
Charleston · 2013-09-05 · via 博客园 - Charleston

我准备在项目中实现该功能之前,google发现大部分代码都是利用一般处理程序HttpHandler实现的服务器端数据的Excel导出,但是这样存在的问题是ashx读取的数据一般都是数据库中视图的数据,难免会含有方便操作的主键ID这列的记录。现在项目需要在easyUI的DataGrid中显示的数据能全部导出Excel,包括DataGrid中的中文标题,其他的统统不要。

完成该功能所需的工具和环境:Newtonsoft.Json序列化和反序列化类库、easyUI前端UI框架、HttpHandler一般处理程序、Aspose.Cells电子表格生成组件;.Net Framework4.0。

前端完成DataGrid中的题头和数据行信息遍历访问,并以JS中二维数组的形式返回后台供ashx程序处理.

function ExportExcel() {
    // 返回grid的所有可见行给后端供导出Excel用
    var rows = $('#userlist').datagrid("getRows");
    if (rows.length == 0) {
        msgShow("没有数据可供导出");
        return;
    }
    //返回grid的所有列的选项title、列宽等
    // var columns = $('#userlist').datagrid("options").columns;

    //定制DataGrid的columns信息,只返回{field:,title:}
    var columns = new Array();
    var fields = $('#userlist').datagrid('getColumnFields');
    for (var i = 0; i < fields.length; i++) {
        var opts = $('#userlist').datagrid('getColumnOption', fields[i]);
        var column = new Object();
        column.field = opts.field;
        column.title = opts.title;
        columns.push(column);
    }
    var excelWorkSheet = new Object();
    excelWorkSheet.rows = rows;
    excelWorkSheet.columns = columns;
    excelWorkSheet.sheetName = "设置导出的Excel工作表名";


    var filename = "/HttpHandlers/FileHandler.ashx?action=exportexcel&excelWorkSheet=" + JSON.stringify(excelWorkSheet);
 
    location.href = filename;
}

  其中FileHandler.ashx是公共的文件处理程序,根据action=Exportexcel来实现Excel导出功能.

 public void ProcessRequest(HttpContext context)
        {
            var action = context.Request["action"];
            switch (action.ToLower())
            {
                case "exportexcel":
                    EasyUIGrid2Excel(context);
                    break;
            }


        }

  EasyUIGrid2Excel完成前台传递的关于Excel报表导出的参数,比如工作表名sheetName,题头标题和行记录。同时它完美解决了在各浏览器下文件名中文乱码问题,最后以弹窗的形式让用户选择直接打开还是下载。

 private void EasyUIGrid2Excel(HttpContext context)
        {
           
            var jsonString = context.Request["excelWorkSheet"];
        //使用Newtonsoft.Json.Linq.JObject将json字符串转化成结构不固定的Class类
            dynamic jsonObject = JObject.Parse(jsonString);

          

            string fileName = String.Concat(jsonObject.sheetName, DateTime.Now.ToString("yyyyMMdd-HHmmss"), ".xls") ;
            
            //解决中文文件名乱码只在IE中有效
            //   filename = HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
            if (context.Request.UserAgent.ToLower().IndexOf("msie") > -1)
            {
                //当客户端使用IE时,对其进行编码;
                //使用 ToHexString 代替传统的 UrlEncode();
                fileName = CommonHelper.ToHexString(fileName);
            }
            if (context.Request.UserAgent.ToLower().IndexOf("firefox") > -1)
            {
                //为了向客户端输出空格,需要在当客户端使用 Firefox 时特殊处理
                
                context.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
            }
            else
                context.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);

            string extension = Path.GetExtension(fileName);
            context.Response.ContentType = CommonHelper.GetMimeType(extension);
            context.Response.ContentEncoding = Encoding.UTF8;
            Workbook workbook = Object2Workbook(jsonObject, context);
            context.Response.Clear();
            context.Response.Buffer = true;

            context.Response.BinaryWrite(workbook.SaveToStream().ToArray());
            
            context.Response.End();
        }

  上面代码中的红色标注部分详见下载中的公共类库,其中Object2Workbook主要实现Aspose.cells中的Excel格式化输出定制,没有太多技巧,Aspose.cells还带有授权文件的哦,你懂的!

 private Workbook Object2Workbook(dynamic jsonObject, HttpContext context)
        {
            #region Aspose.Cell引用
            Aspose.Cells.License licExcel = new License();  //Aspose.Cells申明
            if (File.Exists(context.Server.MapPath("~/Bin/cellLic.lic")))
                licExcel.SetLicense(context.Server.MapPath("~/Bin/cellLic.lic"));
            #endregion

            Workbook workbook = new Workbook();

            Worksheet sheet = workbook.Worksheets[0];


            Styles styles = workbook.Styles;
            int styleIndex = styles.Add();
            Aspose.Cells.Style borderStyle = styles[styleIndex];

            borderStyle.Borders.DiagonalStyle = CellBorderType.None;
            borderStyle.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
            Cells cells = sheet.Cells;
             sheet.FreezePanes(1, 1, 1, 0);//冻结第一行
            sheet.Name = jsonObject.sheetName;//接受前台的Excel工作表名
           


            //为标题设置样式     
            Style styleTitle = workbook.Styles[workbook.Styles.Add()];//新增样式 
            styleTitle.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
            styleTitle.Font.Name = "宋体";//文字字体 
            styleTitle.Font.Size = 18;//文字大小 
            styleTitle.Font.IsBold = true;//粗体 

            //题头样式 
            Style styleHeader = workbook.Styles[workbook.Styles.Add()];//新增样式 
            styleHeader.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
            styleHeader.Font.Name = "宋体";//文字字体 
            styleHeader.Font.Size = 14;//文字大小 
            styleHeader.Font.IsBold = true;//粗体 
            styleHeader.IsTextWrapped = true;//单元格内容自动换行 
            styleHeader.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
            styleHeader.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
            styleHeader.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
            styleHeader.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;

            //内容样式
            Style styleContent = workbook.Styles[workbook.Styles.Add()];//新增样式 
            styleContent.HorizontalAlignment = TextAlignmentType.Center;//文字居中 
            styleContent.Font.Name = "宋体";//文字字体 
            styleContent.Font.Size = 12;//文字大小 
            styleContent.Borders[BorderType.LeftBorder].LineStyle = CellBorderType.Thin;
            styleContent.Borders[BorderType.RightBorder].LineStyle = CellBorderType.Thin;
            styleContent.Borders[BorderType.TopBorder].LineStyle = CellBorderType.Thin;
            styleContent.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;


            var rowCount = jsonObject.rows.Count;//表格行数 
            var columnCount = jsonObject.columns.Count;//表格列数 


            //生成行1 标题行    
            cells.Merge(0, 0, 1, columnCount);//合并单元格 
            cells[0, 0].PutValue(jsonObject.sheetName);//填写内容 
            cells[0, 0].Style = styleTitle;
            cells.SetRowHeight(0, 25);

            //生成题头列行 
            for (int i = 0; i < columnCount; i++)
            {
                cells[1, i].PutValue(jsonObject.columns[i]["title"]);
                cells[1, i].Style = styleHeader;
                cells.SetRowHeight(1, 23);
            }
            //生成内容行,第三行起始
            //生成数据行 
            for (int i = 0; i < rowCount; i++)
            {
                for (int k = 0; k < columnCount; k++)
                {
                    var currentColumnName = jsonObject.columns[k]["field"];
                    cells[2 + i, k].PutValue(jsonObject.rows[i][currentColumnName.Value]);
                    cells[2 + i, k].Style = styleContent;
                }
                 cells.SetRowHeight(2 + i, 22);
            }
            

            //添加制表日期
            cells[2 + rowCount, columnCount-1].PutValue("制表日期:" + DateTime.Now.ToShortDateString());
            sheet.AutoFitColumns();//让各列自适应宽度
            sheet.AutoFitRows();//让各行自适应宽度
            return workbook;
        }

      该code snippet也能很好的移植,在需要实现Excel导出的js文件中调用ExportExcel函数,传递sheetName值即可

       国际惯例,无图无真相

文件下载

btw:另外请教两个问题,知道的童鞋回答一下,谢谢

1,通过客户端导出Excel的方式,当打开文件的时候,提示:文件错误,数据可能丢失, 初步认为可能数字以文本形式存到Excel中出现了问题?如果直接服务器端导出却没有这个错误

2,一对多表中数据更新问题,比如三张表User,Role和对应的关联表UserRole,其中主键都是自动递增ID。如果我更改了用户角色,当前的做法是在UserRole中删掉该用户的所有旧角色,再新增。感觉这样麻烦也不合理,请教大家有好的做饭没?