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,非常方便。完全满足合并单元格(合并行、合并列)的需求。




相关文章
|
1月前
|
安全 测试技术 数据库
维护的Web应用程序
【10月更文挑战第4天】维护的Web应用程序
47 4
|
16天前
|
Java API Apache
|
20天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
25 4
|
21天前
|
数据可视化 数据库 开发者
使用Dash构建交互式Web应用程序
【10月更文挑战第16天】本文介绍了使用Python的Dash框架构建交互式Web应用程序的方法。Dash结合了Flask、React和Plotly等技术,让开发者能够快速创建功能丰富的数据可视化应用。文章从安装Dash开始,逐步介绍了创建简单应用程序、添加交互元素、部署应用程序以及集成更多功能的步骤,并提供了代码示例。通过本文,读者可以掌握使用Dash构建交互式Web应用程序的基本技巧和高级功能。
37 3
|
24天前
|
JavaScript 前端开发 数据处理
Vue导出el-table表格为Excel文件的两种方式
Vue导出el-table表格为Excel文件的两种方式
|
1月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
1月前
|
JavaScript 前端开发
如何使用Vue.js构建响应式Web应用程序
【10月更文挑战第9天】如何使用Vue.js构建响应式Web应用程序
|
1月前
|
前端开发 JavaScript 测试技术
构建响应式Web应用程序:React实战指南
【10月更文挑战第9天】构建响应式Web应用程序:React实战指南
|
1月前
|
存储 JavaScript 前端开发
如何使用React和Redux构建现代化Web应用程序
【10月更文挑战第4天】如何使用React和Redux构建现代化Web应用程序
|
1月前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
235 0