之前实现了html直接转换为word文档的功能,那么是否也同样可以直接转换为pdf文档呢,网上搜了下html to pdf 的开源插件有很多 如:wkhtmltopdf,pdfsharp,itextsharp等

本文使用itextsharp实现如何将html文件转换为pdf文档

 

首先使用Nuget安装itextsharp插件

  1. Install-Package itextsharp.xmlworker

创建FileContentResult文件继承自ActionResult,方法HtmlToPdf中实现了如何将一段html转换为pdf文档逻辑,itextsharp.xmlworker能够支持丰富的css和html标签,但是有一个很大的缺点就是不支持中文,网上的一些解决中文字体的逻辑,在新版里面已经不支持了,在以下的示例代码中已经解决此问题,重点是以下两部代码:

FontFactory.RegisterDirectories();//注册当前系统中所支持的字体

worker.ParseXHtml(pdfWriter, document, new MemoryStream(Encoding.UTF8.GetBytes(sbHtml.ToString())), null, Encoding.UTF8, new UnicodeFontFactory()); //指定要使用的字体

 

  1. public
    class PdfContentResult : ActionResult
  2. {
  3.     public PdfContentResult() : this(null, null) { }
  4.  
  5.     public PdfContentResult(string viewName) : this(null, viewName) { }
  6.  
  7.     public PdfContentResult(object model) : this(model, null) { }
  8.  
  9.     public PdfContentResult(object model, string viewName)
  10.     {
  11.         this.ViewName = viewName;
  12.         ViewData = null != model ? new ViewDataDictionary(model) : null;
  13.     }
  14.  
  15.     public ViewDataDictionary ViewData { get; set; } = new ViewDataDictionary();
  16.  
  17.     public
    string ViewName { get; set; }
  18.  
  19.     public IView View { get; set; }
  20.  
  21.     public
    override
    void ExecuteResult(ControllerContext context)
  22.     {
  23.         if (String.IsNullOrEmpty(ViewName))
  24.         {
  25.             ViewName = context.RouteData.GetRequiredString("action");
  26.         }
  27.         if (ViewData == null)
  28.         {
  29.             ViewData = context.Controller.ViewData;
  30.         }
  31.         ViewEngineResult result = ViewEngines.Engines.FindView(context, ViewName, null);
  32.         View = result.View;
  33.  
  34.         StringBuilder sbHtml = new StringBuilder();
  35.         TextWriter txtWriter = new StringWriter(sbHtml);
  36.         ViewContext viewContext = new ViewContext(context, View, ViewData, context.Controller.TempData, txtWriter);
  37.         result.View.Render(viewContext, txtWriter);
  38.  
  39.         HttpResponseBase httpResponse = context.HttpContext.Response;
  40.         httpResponse.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
  41.  
  42.         //加入此头部文件会直接下载pdf文件,而不是在浏览器中预览呈现
  43.         //context.HttpContext.Response.AppendHeader("Content-Disposition", string.Format("attachment;filename={0}.pdf", ViewName));
  44.  
  45.         HtmlToPdf(sbHtml, httpResponse);
  46.  
  47.         result.ViewEngine.ReleaseView(context, View);
  48.     }
  49.  
  50.     private
    static
    void HtmlToPdf(StringBuilder sbHtml, HttpResponseBase httpResponse)
  51.     {
  52.         using (Document document = new Document(PageSize.A4, 4, 4, 4, 4))
  53.         {
  54.             using (PdfWriter pdfWriter = PdfWriter.GetInstance(document, httpResponse.OutputStream))
  55.             {
  56.                 document.Open();
  57.                 FontFactory.RegisterDirectories();//注册系统中所支持的字体
  58.                 XMLWorkerHelper worker = XMLWorkerHelper.GetInstance();
  59.                 //UnicodeFontFactory 自定义实现解决itextsharp.xmlworker 不支持中文的问题
  60.                 worker.ParseXHtml(pdfWriter, document, new MemoryStream(Encoding.UTF8.GetBytes(sbHtml.ToString())), null, Encoding.UTF8, new UnicodeFontFactory());
  61.                 document.Close();
  62.             }
  63.         }
  64.     }
  65. }

 

UnicodeFontFactory完整代码

 

  1. public
    class UnicodeFontFactory : FontFactoryImp
  2. {
  3.     static UnicodeFontFactory()
  4.     {
  5.  
  6.     }
  7.     public
    override Font GetFont(string fontname, string encoding, bool embedded, float size, int style, BaseColor color, bool cached)
  8.     {
  9.         return FontFactory.GetFont("arial unicode ms", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
  10.     }
  11. }

 

 

如何确定哪些字体在itextsharp中是支持中文的呢,可以通过下面这个小程序验证输出所有的字体名称,及是否支持中文

通过控制台应用程序执行完成后,打开生成的pdf文件,查看 字体名称是否有中文 " 我支持中文" ,如果存在则表示支持中文,否则不支持中文

  1. Document document = new Document();
  2. PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(@"c:\pdf\pdf.pdf", FileMode.Create));
  3. document.Open();
  4.  
  5. FontFactory.RegisterDirectories();
  6.  
  7. foreach (var item in FontFactory.RegisteredFonts)
  8. {
  9.     Font font = FontFactory.GetFont(item, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
  10.     document.Add(new Paragraph(item + "<p>我支持中文</p>", font));
  11. }
  12. document.Close();

 

 

上面说了如何转换html为pdf及怎么解决中文字体的问题,那么怎么使用定义的PdfContentResult呢,

使用方式一:直接在控制器的Action方法中返回PdfContentResult实例

  1. public
    class PdfController : Controller
  2.     {
  3.         // GET: Pdf
  4.         public ActionResult Index()
  5.         {
  6.             return
    new PdfContentResult(null,"index");
  7.         }
  8.     }

 

使用方式二:添加Controller类的拓展方法,然后在控制器的Action方法中返回对应的拓展方法

  1. public
    static
    class ControllerExtensions
  2.   {
  3.       public
    static PdfContentResult Pdf(this Controller controller, object model)
  4.       {
  5.           return
    new PdfContentResult(model);
  6.       }
  7.  
  8.       public
    static PdfContentResult Pdf(this Controller controller, object model, string fileName)
  9.       {
  10.           return
    new PdfContentResult(model, fileName);
  11.       }
  12.  
  13.       public
    static PdfContentResult Pdf(this Controller controller, string fileName)
  14.       {
  15.           return
    new PdfContentResult(fileName);
  16.       }
  17.   }

 

这种感觉用起来是不是与return view();一样

  1. public
    class PdfController : Controller
  2. {
  3.     // GET: Pdf
  4.     public ActionResult Index()
  5.     {
  6.         return
    this.Pdf(null, "index");
  7.     }
  8. }

 

可能有人会问pdf文档的内容在哪里维护,直接打开Action对应的View视图,像写mvc页面一样布局pdf内容就可以了

 

至于itextsharp更多功能支持,请参考此文档:http://developers.itextpdf.com/

ASP.NET MVC 拓展ActionResult实现Html To Pdf 导出的更多相关文章

  1. Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html

    Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html 1.前言 上一篇文章我开源了轮子,Asp.net Core 3.1 Razor视图模版动态渲染PDF,然后,很 ...

  2. [转载]深入理解ASP.NET MVC之ActionResult

    Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...

  3. Asp.net MVC 之 ActionResult

    Action运行完后,回传的值通过ActionResult 类别或者其衍生的类别操作.ActionResult是一个抽象类,因此,Asp.net MVC 本身就实作了许多不同类型的ActionResu ...

  4. asp.net mvc之ActionResult

    Web服务器接收到一个客户端请求以后,会对请求予以相应,而这个响应是通过Response来控制的, 但是在asp.net mvc 里,这部分的工作是由ActionResult来完成的, ActionR ...

  5. ASP.NET MVC自定义ActionResult实现文件压缩

    有时候需要将单个或多个文件进行压缩打包后在进行下载,这里我自定义了一个ActionResult,方便进行文件下载 using System; using System.Collections; usi ...

  6. ASP.NET MVC 拓展ViewResult实现word文档下载

      最近项目中有同事用到word文档导出功能,遇到了一些导出失败问题,帮其看了下解决问题的同事,看了下之前的代码发现几个问题: 代码编写不规范,word导出功能未收口 重复代码导出都是 实现逻辑比较复 ...

  7. ASP.NET MVC 中 ActionResult 和 ViewResult 在使用上的区别

    如果确认你返回的是一个视图(view),你可以直接返回类型为ViewResult. 如果你并不是很清楚,或者你根本不想去理解这些东西,你可以直接返回ActionResult

  8. Asp.net MVC 控制器ActionResult的例子

    ActionResult 父类型 ViewResult View() 多重载应用 PartialViewResult PartialView() 部分试图 New EmptyResult()  空 如 ...

  9. Asp.net MVC 之ActionResult

    ActionResult 派生出以下子类: ViewResult 返回一个网页视图 PartialViewResult 返回一个网页视图,但不适用布局页. ContentResult 返回一段字符串文 ...

随机推荐

  1. SSH实例(4)

    Clas.hbm.xml文件如下: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibe ...

  2. Validating HTTP data with Play

    Validations ensure that the data has certain values or meets specific requirements. You can use vali ...

  3. Javascript 语言精粹 代码片段合集

    Javascript 语言精粹 代码片段合集 标签:Douglas-Crockford Javascript 最佳实践 原文链接 更好的阅读体验 使用一个method 方法定义新方法 Function ...

  4. knockout源码分析之执行过程

    一.执行流程 二.主要类分析 2.1. 在applyBindings中,创建bindingContext,然后执行applyBindingsToNodeAndDescendantsInternal方法 ...

  5. Perfect Scrollbar – 完美的 jQuery 滚动条插件

    Perfect Scrollbar 是一个很小的,但完美的 jQuery 滚动插件.滚动条不会影响原来的设计布局,滚动条的设计是完全可定制的.你可以改变几乎所有的 CSS 样式的滚动条,滚动条设计对脚 ...

  6. Java2_JDK的安装和配置

    什么是JDK JDK就是Java Development Kit,java开发工具包,由sun公司开发. JDK的三个版本 桌面系统或应用程序的标准版(Java 2 Platform Standard ...

  7. 百度地图API使用方法详解

    最近做了个项目,其中项目中有个需求需要用到百度地图进行导航,通过查阅相关资料参考百度地图api完成了一个例子. API地址:http://developer.baidu.com/map/jsdemo. ...

  8. SharePoint 使用脚本为表单绑定事件

    在SharePoint的使用过程中,我们经常需要为表单页面做一些特殊处理,比如说新建页面的时候有多选项的字段,但是只能选择指定数量的选项,尤其在新闻列表或者调查列表等特殊场景中,广泛使用. 下面,我们 ...

  9. Basic Virus's Infection & Variation [Python]

    Learn from here Initial #!/usr/bin/python2.7 #MAGIC_STRING_skd83749872 import os import __main__ imp ...

  10. 《Kotli­n for ­androi­d Deve­lopers­》中文翻译

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4939080.html 之前一直在关注Kotlin和Androi ...