之前实现了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. 让 ListView 在 Android 可回弹

    说明:让 ListView 在 Android 可回弹. 适用:Delphi XE5 修改:找出 FMX.Platform.Android.pas 档案,并复制到自己的 Project 路径里,找到 ...

  2. 实现在ios开发中的App滑动封面 UIScrollView

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. _scrol ...

  3. 怎样给Eclipse添加一个Xml模板

    1.找到Window/Preferences/XML/XML Files/Editor/Templates 2.新建一个模板,设置一个名称并且在Pattern中设置自己的XML模板就可以了,同时支持导 ...

  4. hdu-4496-D-City

    D-City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...

  5. MyEclipse10 中的两种FreeMarker插件的安装与配置

    第一个插件是:                                       freemarker-ide MyEclipce10.0中安装FreeMarker插件,这绝对是最简单的方法 ...

  6. easyui datagrid 分页略解

    easyui datagrid 本身自带了分页功能. 但是这个需要你自己控制. 在后台可以得到两个datagrid的参数,rows 和page.其中rows是每页要显示的个数,page是第几页.单纯的 ...

  7. Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.

    遇到这个问题似然重启是个办法,但是真心好累.. 1.在dos下,输入  netstat   -ano|findstr  8080 //说明:查看占用8080端口的进程 显示占用端口的进程 2.在任务管 ...

  8. 点击div全选中再点击取消全选div里面的文字

    想做一个就是点击一个div然后实现的功能是div里面的文字都成选中状态,然后就可以利用浏览器的自带的复制功能,任意复制在哪里去了 在网上百度了一下 然后网上的答案感觉很大的范围 然后一些搜索 然后就锁 ...

  9. 25款专业的 WordPress 电子商务网站主题

    WordPress 作为最流行的博客系统,插件众多,易于扩充功能.安装和使用都非常方便,而且有许多第三方开发的免费模板,安装方式简单易用.这篇文章和大家分享35款专业的 WordPress 电子商务网 ...

  10. 知道吗?9个搜索引擎优化(SEO)最佳实践

    作为网页设计师,搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变.穴居人拥有洞穴壁画,古埃及人有象形文字, ...