Web程序导出Excel文档

简介: 版权声明:欢迎评论和转载,转载请注明来源。 https://blog.csdn.net/zy332719794/article/details/8938475         今天接到一个任务,把数据库里面的数据导出到Excel文档。
版权声明:欢迎评论和转载,转载请注明来源。 https://blog.csdn.net/zy332719794/article/details/8938475

        今天接到一个任务,把数据库里面的数据导出到Excel文档。系统是Web程序的,使用的是MVC架构。第一个想法是很简单,保存.csv文件。做法是首先把数据读到一个DataTable里面,然后将数据分隔写入文件就OK了,最后在相应请求下载文件。

代码如下:

	/// <summary>
        /// 导出数据
        /// </summary>
        public ActionResult ExportData(int processId)
        {
            var myProcessId = processId;

            var items = db.NecessaryMaterialsDbSet.Include(p => p.ProcessItem)
                          .OrderBy(p => p.Category)
                          .ToList()
                          .Where(p => p.ProcessItem.Id == processId);

            if (!items.Any())
            {
                return RedirectToAction("Index", new { processId = myProcessId });
            }

            var dt = new DataTable();

            dt.Columns.Add("类别");
            dt.Columns.Add("材料名称");
            dt.Columns.Add("材料来源");
            dt.Columns.Add("来源类型");
            dt.Columns.Add("原件、复印件");
            dt.Columns.Add("备注");

            foreach (var materialse in items)
            {
                dt.Rows.Add(materialse.Category,
                            materialse.Name,
                            materialse.Source,
                            materialse.SourceType,
                            materialse.OriginalOrCopy,
                            materialse.Note);
            }
            
            //生成文件
            string fileName = items.First().ProcessItem.ProcessName + "-必备材料.csv";

            var sw = new StringWriter();
            var title = new StringBuilder();

            title.Append(dt.Columns[0].ColumnName);

            for (int i = 1; i < dt.Columns.Count; i++)
            {
                title.AppendFormat(",{0}", dt.Columns[i].ColumnName);
            }

            sw.WriteLine(title);

            var content = new StringBuilder();

            foreach (DataRow row in dt.Rows)
            {
                content.Append(row[0]);

                for (int i = 1; i < dt.Columns.Count; i++)
                {
                    content.AppendFormat(",{0}", row[i]);
                }

                sw.WriteLine(content);
                content.Clear();
            }

            sw.Close();

            Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(fileName));
            Response.ContentType = "vnd.ms-excel.numberformat:yyyy-MM-dd ";
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
            Response.Write(sw);
            Response.End();
            
            return RedirectToAction("Index", new { processId = myProcessId });
        }

但是有个问题,我需要导出有合并单元格的样式的Excel,这样似乎不能实现。

如下图所示:


第一个想法是使用Office的Excel的API,有个同事建议使用Table来构造。结果试了下,果然不错。

构造方法如在html里面构造一样。使用<table><tr><tb>标签来控制行和列以及内容。

同时还可以在table里面设置属性,如<table border='1'>、<td width='100'><br>等等。

其中跨行就用rowspan属性来设置,如:"<td  rowspan=5>表示跨5行(合并单元格)。

原来还有这样好的方法,于是按照这种方式写了代码,调试生成,效果非常好,上面的图就是用table的方法生成的。

下面我贴上一些实例代码:

ExpMaterialsToExcelModel.cs(这个是用来存将导出的数据类结构)

    public class ExpMaterialsToExcelModel
    {
        /// <summary>
        /// 流程名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 审批事项
        /// </summary>
        public List<Category> Categorys { get; set; }

        public ExpMaterialsToExcelModel()
        {
            Categorys = new List<Category>();
        }
    }

    public class Category
    {
        /// <summary>
        /// 审批事项名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 承办科室
        /// </summary>
        public string Department { get; set; }

        /// <summary>
        /// 联系人及电话
        /// </summary>
        public string PersonAndPhone { get; set; }

        /// <summary>
        /// 材料
        /// </summary>
        public List<MaterialsInfo> MaterialsList { get; set; }

        public Category()
        {
            MaterialsList = new List<MaterialsInfo>();
        }
    }

    public class MaterialsInfo
    {
        /// <summary>
        /// 排号顺序
        /// </summary>
        public int SortNumb { get; set; }

        /// <summary>
        /// 材料名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 来源类型
        /// </summary>
        public string SourceType { get; set; }

        /// <summary>
        /// 来源
        /// </summary>
        public string Source { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Note { get; set; }
    }

ExpMaterialsToExcelModel.cs(从数据库读取数据)

	private ExpMaterialsToExcelModel GetExpData(int processId)
        {
		代码略。。。
	}


GetExpString(生成导出的table文本)重点

private StringBuilder GetExpString(ExpMaterialsToExcelModel tableData)
        {
            int rowCount = tableData.Categorys.Sum(category => category.MaterialsList.Count);

            var str = new StringBuilder();
            str.Append("<meta http-equiv=\"content-type\" content=\"application/excel;charset=utf-8\" />");
            str.Append("<table border='1'>");
            str.Append("<tr>");
            str.AppendFormat("<td width='100' rowspan='{0}'>{1}</td>", rowCount, tableData.Name);

            for (int i = 0; i < tableData.Categorys.Count; i++)
            {
                if (i > 0)
                {
                    str.Append("<tr>");
                }

                var category = tableData.Categorys[i];

                rowCount = category.MaterialsList.Count;
                str.AppendFormat("<td width='100' rowspan='{0}'>{1}</td>", rowCount, category.Name);

                str.AppendFormat("<td width='100'>{0}</td>", category.MaterialsList[0].SourceType);
                str.AppendFormat("<td width='200'>{0}.{1}</td>", category.MaterialsList[0].SortNumb,
                                 category.MaterialsList[0].Name);
                str.AppendFormat("<td width='100'>{0}</td>", category.MaterialsList[0].Note);

                str.AppendFormat("<td width='100' rowspan='{0}'>{1}</td>", rowCount, category.Department);
                str.AppendFormat("<td width='100' rowspan='{0}'>{1}</td>", rowCount, category.PersonAndPhone);
                str.Append("</tr>");

                for (int j = 1; j < category.MaterialsList.Count; j++)
                {
                    str.Append("<tr>");
                    str.AppendFormat("<td width='100'>{0}</td>", category.MaterialsList[j].SourceType);
                    str.AppendFormat("<td width='200'>{0}.{1}</td>", category.MaterialsList[j].SortNumb,
                                     category.MaterialsList[j].Name);
                    str.AppendFormat("<td width='100'>{0}</td>", category.MaterialsList[j].Note);
                    str.Append("</tr>");
                }
            }

            str.Append("</table>");

            return str;
        }


ExportData方法(页面请求,返回和下载文件)

	/// <summary>
        /// 导出数据
        /// </summary>
        public ActionResult ExportData(int processId)
        {
            var tableData = GetExpData(processId);
            var tableString = GetExpString(tableData);

            // 输出Excel
            string fileName = tableData.Name + "材料清单";
            Response.ClearContent();
            Response.AddHeader("content-disposition", 
                string.Format("attachment; filename={0}.xls", 
                HttpUtility.UrlEncode(fileName, Encoding.UTF8)));
            Response.ContentType = "application/excel";
            Response.Charset = "utf-8";
            Response.Write(tableString);
            Response.End();


            var myProcessId = processId;
            return RedirectToAction("Index", new { processId = myProcessId });
        }

这种方法省去了去调用繁琐的Excel API,非常方便。完全满足合并单元格(合并行、合并列)的需求。




相关文章
|
12月前
|
弹性计算 监控 网络安全
如何轻松使用AWS Web应用程序防火墙?
AWS WAF是Web应用防火墙,可防护常见网络攻击。通过创建Web ACL并设置规则,保护CloudFront、API网关、负载均衡器等资源。支持自定义规则与OWASP预定义规则集,结合CloudWatch实现监控日志,提升应用安全性和稳定性。
|
安全 JavaScript 前端开发
AppSpider 7.5.020 发布 - Web 应用程序安全测试
AppSpider 7.5.020 for Windows - Web 应用程序安全测试
321 0
|
存储 安全 Java
如何在 Spring Web 应用程序中使用 @SessionScope 和 @RequestScope
Spring框架中的`@SessionScope`和`@RequestScope`注解用于管理Web应用中的状态。`@SessionScope`绑定HTTP会话生命周期,适用于用户特定数据,如购物车;`@RequestScope`限定于单个请求,适合无状态、线程安全的操作,如日志记录。合理选择作用域能提升应用性能与可维护性。
462 1
|
12月前
|
小程序
公众号如何添加附传Word、Excel、Pdf、PPT文档
公众号里添加一些文档给公众号粉丝下载,比如课件PPT、申请表Word文档、岗位需求Excel表、大赛入围/获奖名单等。公众号本身是不支持直接上传文件的,但我们可以通过附件小程序“间接”上传文件。
1752 0
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
1244 157
Excel中如何批量重命名工作表与将每个工作表导出到单独Excel文件
本文介绍了如何在Excel中使用VBA批量重命名工作表、根据单元格内容修改颜色,以及将工作表导出为独立文件的方法。同时提供了Python实现导出工作表的代码示例,适用于自动化处理Excel文档。
|
安全 测试技术 Linux
Acunetix v25.4 发布 - Web 应用程序安全测试
Acunetix v25.4 (Linux, Windows) - Web 应用程序安全测试
545 3
Acunetix v25.4 发布 - Web 应用程序安全测试
|
安全 Devops 测试技术
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
298 0
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
|
安全 JavaScript Java
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
312 12
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
|
JavaScript 前端开发 数据可视化
20.6K star!Excel级交互体验!这款开源Web表格神器绝了!
Handsontable 是一款功能强大的 JavaScript 数据表格组件,提供类 Excel 的交互体验。支持实时协作、数据绑定、公式计算等企业级功能,可轻松集成到 React/Vue/Angular 等主流框架。
3200 11