asp.net mvc 模板生成word文档
来源:互联网 发布:mac系统清理工具 免费 编辑:程序博客网 时间:2024/05/16 05:30
自从ms office 2007开始.就开始支持open xml.而且发布了一套api.还有个对应的 open xml tool,我看了一下,觉得不值得花这个力气去熟悉一套非标准的api,在网上查资料的时候,我知道了原来docx的原来就是一个标准zip包,试着解压来看了看,文件结构比较简单,如果忽略掉文件之样的关联引用.完成可以自己生成xml,然后再打包成docx.为什么不呢,这样应该相当的简单.当然中间我也走了一点弯路,比如可恶的zippackage.好了.让我们开始吧.
step 1:当然是我们的controller.
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using CJRApp2.Data;using System.IO;using System.Text;using ICSharpCode.SharpZipLib.Zip;using ICSharpCode.SharpZipLib.Checksums;namespace CJRApp2.Web.Controllers{ public class CreatedocController : Controller { /// <summary> /// uri调用格式可能为Createdoc?templateName=simple&arg=1&key=value /// </summary> /// <param name="templateName"></param> /// <returns></returns> public ActionResult Index(string templateName) { //WebFormView //我们的约定是模板应该生成两个ViewData //入口为模板名,参数设置应该模板文件自己去分析uri //docx用于存放文件内容 //docName用于存放下载后的文件名 this.transView("~/Views/Createdoc/" + templateName + ".aspx"); byte[] bytes = this.ViewData["docx"] as byte[]; return this.File(bytes , "application/vnd.openxmlformats-officedocument.wordprocessingml.document" , this.ViewData["docName"] + ".docx"); } /// <summary> /// 由视图产生输出字符串,docx中的xml默认是utf-8无签名的.如果改用.aspx视图动态输出记得另存为有签名的 /// </summary> /// <param name="viewName">视图文件名</param> /// <returns>视图结果</returns> private string transView(string viewName) { ViewEngineResult ver = ViewEngines.Engines.FindView(this.ControllerContext, viewName, null); StringWriter sw = new StringWriter(); ViewContext vc = new ViewContext(this.ControllerContext, ver.View, this.ViewData, this.TempData, sw); ver.View.Render(vc, sw); ver.ViewEngine.ReleaseView(this.ControllerContext, ver.View); sw.Flush(); string returnValue = sw.GetStringBuilder().ToString(); sw.Close(); sw.Dispose(); return returnValue; } /// <summary> /// 转换视图结果进压缩包 /// </summary> /// <param name="zs">压缩文件输出流</param> /// <param name="uri">压缩文件uri</param> /// <param name="viewName">视图文件名,形如~/Views/ctrollername/templatename/word/document.aspx</param> /// <returns></returns> public void transView2zip(ZipOutputStream zs, string uri, string viewName) { string fileContent=this.transView(viewName); ZipEntry entry = new ZipEntry(uri); zs.PutNextEntry(entry); byte[] bytes = Encoding.UTF8.GetBytes(fileContent); zs.Write(bytes, 0, bytes.Length); } /// <summary> /// 添加源文件到压缩包 /// </summary> /// <param name="zs">压缩文件输出流</param> /// <param name="uri">压缩文件uri</param> /// <param name="file">本地文件全</param> public void AddFile2zip(ZipOutputStream zs,string uri,string file) { FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read); ZipEntry entry = new ZipEntry(uri); zs.PutNextEntry(entry); fs.CopyTo(zs); fs.Flush(); fs.Close(); fs.Dispose(); } }}step 2:现在我们希望有一个模板文件template.aspx提供zip包存放在ViewData["docx"]中就可以提供服务了,它应该就是一个根据需要生成zip包的过程,我们先创建一个simple.aspx的视图文件,建立一个simple的对应目录存放解压后的docx,可能的结构如图所示
现在开始我们的simple.aspx吧.
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %><%@ import namespace="CJRApp2.Web.Controllers" %><%@ import namespace="System.IO" %><%@ import namespace="ICSharpCode.SharpZipLib.Zip" %><% //文件名应该为~/......xxx.aspx? CreatedocController ctrl = ViewContext.Controller as CreatedocController; HttpContextBase http = ViewContext.HttpContext; string viewpath = (this.ViewContext.View as WebFormView).ViewPath; string filePath = viewpath.Substring(0, viewpath.Length - 5) + "\\"; filePath = Server.MapPath(filePath); // String[] files= Directory.GetFileSystemEntries(filePath); IEnumerable<string> files= Directory.EnumerateFiles(filePath, "*", SearchOption.AllDirectories); using (MemoryStream ms = new MemoryStream()) { //不要考虑ZipPackage,微软自己都说它不是一个标准的zip,试试SharpZip using (ZipOutputStream zs = new ZipOutputStream(ms)) { zs.UseZip64 = UseZip64.Off; //非aspx直接进压缩包 foreach (string file in files) { string uri = file.Substring(filePath.Length); if (!uri.EndsWith(".aspx")){ ctrl.AddFile2zip(zs, uri, file); } } //现在我们修改了word/document.xml=>word/document.aspx //事实上可以用同一个aspx生成不同的xml然后进压缩包,比如类似的chart //实现在里面document.aspx ctrl.transView2zip(zs, "word/document.xml", "~/views/createdoc/simple/word/document.aspx"); } //设置ctrl.ViewData 以返回数据,现在所有的生成过程都是在viewpage中完成的 //至于controller 会读取 ViewData,然后以docName指定的名字返回压缩文件,也就是docx ctrl.ViewData["docx"] = ms.ToArray(); ctrl.ViewData["docName"] = "下载后的文件名为simple"; }%>step3:很好,它开始工作了.但这不是我们所需要的.我们的工作应该是document.aspx,因为我们需要它来动态的生成word/document.xml,尝试重命word\documents.xml为
aspx,simple能根据我们定义的规则输出视图并添加入zip包,这很轻松,不是吗,当然有点小小的友情提供.docx解压出来的xml文件是utf-8(无签名)格式的,需要另存为有签名的,为了方便我们修改document.aspx.我们可能需要格式化xml.记得不要在xml文档声明之前添加回车.换行.可能会导致文档的开始部分有点点丑.它的第一行可能是这样的
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
我们可以试着加入我们的逻辑在这个document.aspx中.比如做为示例.我添加了一点点内容
<%foreach (string key in Request.QueryString.AllKeys) { %> <w:p w:rsidR="003047AC" w:rsidRDefault="003047AC"> <w:pPr> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> <w:t><%=key + ":" + Request.QueryString[key]%></w:t> </w:r> </w:p> <%} %>
step 4:收工.总结一下,我们需要提供的是一个aspx文件和一个对应的docx解压目录.aspx用于指导怎么生成压缩包.压缩包里的文档就是我们的docx模板.需要动态生成的部分可以完全在里面实现.不需要任何多余的东西.再添加一个模板将会是一件很轻松的事,而且重要的是你不再需要重新生成你的工程项目.
- asp.net mvc 模板生成word文档
- Asp.net或C#使用word模板生成替换后的Word和pdf文档-总结
- asp.net HTML生成WORD文档
- ASP.net生成导出WORD文档
- asp生成WORD文档
- Asp生成Word文档
- 在asp.net生成的word文档中插入图片
- ASP.NET生成WORD文档服务器部署注意事项
- ASP.NET生成WORD文档服务器部署注意事项
- Asp.net动态生成Word文档并填充数据
- 使用Asp.Net生成Word文档并直接下载
- 使用ASP.NET生成Word文档并直接下载
- ASP.NET生成WORD文档,服务器部署注意事项
- ASP.NET生成WORD文档服务器部署注意事项
- Asp.net动态生成Word文档并填充数据 转
- ASP.NET生成WORD文档服务器部署注意事项
- asp.net 生成word
- ASP.NET MVC模板
- Hadoop作业提交分析(一)
- 字符数组之间赋值
- VC常见错误:>nafxcwd.lib(afxmem.obj) : error LNK2005
- DP之花店橱窗布置
- RMAN - 备份与恢复实践 之二
- asp.net mvc 模板生成word文档
- SIP协议详解(中文)-3
- C# InputManager示例
- 整数划分(三)
- Android使用"中国天气网"API数据通过城市名称获取天气情况
- java ssh 框架下 利用junit4 spring-test进行单元测试
- PC游戏引擎
- Android Studio Gradle 'XXX' project refresh failed:Unable to start the daemon process
- jwchat代码解释