之前实现了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. Android使用SAX解析XML(6)

    应用截图: (1)开始运行时 (2)选择学院 (3)选择专业 (4)选择班级 (5)选择班级的详细信息 本文参考了<Android平台开发之旅>.

  2. 关于Class.getResource和ClassLoader.getResource的路径问题

    Java中取资源时,经常用到Class.getResource和ClassLoader.getResource,这里来看看他们在取资源文件时候的路径问题. Class.getResource(Stri ...

  3. hibernate----N-N--(人与地点)

    package com.ij34.dao; import java.util.HashSet; import java.util.Set; import javax.persistence.*; @E ...

  4. Java并发编程:进程和线程之由来

    Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...

  5. mysql autocommit=OFF导致wordpress 建立数据库连接时出错

    今天安装wordpress完成后跳转到login页面时,出现建立数据库连接时出错.网上清一色的拷贝http://mt.sohu.com/20160917/n468547634.shtml的答案. 只能 ...

  6. 服务器端高性能的IO模型 转自酷勤网

    服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(BlockingIO):即传统的IO模型. (2)同步非阻塞IO(Non-blockingIO):默认创建的soc ...

  7. WebSocket 学习笔记--IE,IOS,Android等设备的兼容性问题与代码实现

    一.背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏览器来实现,其中数据通信,准备使用WebSocket的方式.于是,我开始 ...

  8. C# 泛型的协变和逆变

    1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量.协变和逆变是两个相互对立的概念: 如 ...

  9. SAP ABAP将大数据量排序后输入到内表

    要向内表读入3百50万条数据,如果一次读入就会产生运行错误,错误提示为,没有内存对于扩展 内表. 我考虑使用SELECT...INTO TABLE...PACKAGE SIZE 和ENDSELECT来 ...

  10. SharePoint 向多行文本类型字段插入特殊类型链接

    1.在测试列表中插入一个多行文本字段,名字叫做Content,如下图: 2.在Content字段里,添加一个Link,如下图: 3.尝试输入Notes格式的Link,如下图: 4.点击OK的时候,弹出 ...