asp.net MVC设计模式中使用iTextSharp实现html字符串生成PDF文件
因个人需求,需要将html格式转换成PDF并加上水印图片。于是乎第一次接触这种需求的小菜鸟博主我,在某度搜索引擎上不断的查阅关键字资料、踩坑,终于有了一个相应的解决方案。以下是解决步骤,记录下来方便以后的回顾,以及各位大神们的品鉴。
1、在 NuGet 搜索 itextsharp 关键字 下载以下截图圈中的两个包,一般下载完后项目会自引用。
2、在项目文件中引入以下命名空间(建议下面提及的代码封装成类库,方便项目间调用,个人取舍)
3、Html字符串转pdf文件流,加水印图片以及未加水印重载 精简帮助类(由博主踩坑整理,仅完成个人业务需求)
/// <summary>
/// Html字符串转PDF输出帮助类
/// </summary>
public class HtmlToPdfHelper
{
#region HtmlToPDF /// <summary>
/// 判断是否有乱码
/// </summary>
/// <param name="txt"></param>
/// <returns></returns>
private static bool IsMessyCode(string txt)
{
var bytes = Encoding.UTF8.GetBytes(txt);
for (var i = ; i < bytes.Length; i++)
{
if (i < bytes.Length - )
if (bytes[i] == && bytes[i + ] == && bytes[i + ] == )
{
return true;
}
}
return false;
} /// <summary>
/// 将Html字符串 输出到PDF档里
/// </summary>
/// <param name="htmlText"></param>
/// <returns></returns>
public static byte[] ConvertHtmlTextToPdf(string htmlText)
{
return ConvertHtmlTextToPdf(htmlText, "", , , , );
} /// <summary>
/// 将Html字符串 输出到PDF档里,并添加水印
/// </summary>
/// <param name="htmlText">网页代码</param>
/// <param name="picPath">水印路径</param>
/// <param name="left">距离左边距离</param>
/// <param name="top">距顶部距离</param>
/// <param name="width">水印宽度</param>
/// <param name="height">水印高度</param>
/// <returns></returns>
public static byte[] ConvertHtmlTextToPdf(string htmlText, string picPath, int left, int top, int width, int height)
{
if (string.IsNullOrEmpty(htmlText))
{
return null;
}
//避免当htmlText无任何html tag标签的纯文字时,转PDF时会挂掉,所以一律加上<p>标签
htmlText = "<p>" + htmlText + "</p>";
MemoryStream outputStream = new MemoryStream();//要把PDF写到哪个串流
byte[] data = Encoding.UTF8.GetBytes(htmlText);//字串转成byte[]
MemoryStream msInput = new MemoryStream(data);
Document doc = new Document();//要写PDF的文件,建构子没填的话预设直式A4
PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);
//指定文件预设开档时的缩放为100%
PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, , doc.PageSize.Height, 1f);
//开启Document文件
doc.Open(); //写入水印图片
if (!string.IsNullOrEmpty(picPath))
{
Image img = Image.GetInstance(picPath);
//设置图片的位置
img.SetAbsolutePosition(width + left, (doc.PageSize.Height - height) - top);
//设置图片的大小
img.ScaleAbsolute(width, height);
doc.Add(img);
}
try
{
//使用XMLWorkerHelper把Html parse到PDF档里
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8);
//将pdfDest设定的资料写到PDF档
PdfAction action = PdfAction.GotoLocalPage(, pdfDest, writer);
writer.SetOpenAction(action);
}
catch (Exception)
{
return null;
}
doc.Close();
msInput.Close();
outputStream.Close();
//回传PDF档案
return outputStream.ToArray();
} #endregion }
4、获取网页字符串方法
/// <summary>
/// 获取网站内容,包含了 HTML+CSS+JS
/// </summary>
/// <returns>String返回网页信息</returns>
public static string GetWebContent(string inpath)
{
try
{
WebClient myWebClient = new WebClient();
//获取或设置用于向Internet资源的请求进行身份验证的网络凭据
myWebClient.Credentials = CredentialCache.DefaultCredentials;
//从指定网站下载数据
Byte[] pageData = myWebClient.DownloadData(inpath);
//如果获取网站页面采用的是GB2312,则使用这句
string pageHtml = Encoding.UTF8.GetString(pageData);
bool isBool = IsMessyCode(pageHtml);//判断使用哪种编码 读取网页信息
if (!isBool)
{
string pageHtml1 = Encoding.UTF8.GetString(pageData);
pageHtml = pageHtml1;
}
else
{
string pageHtml2 = Encoding.Default.GetString(pageData);
pageHtml = pageHtml2;
}
return pageHtml;
}
catch (WebException webEx)
{
return webEx.Message;
}
}
5、MVC设计模式下获取控制器视图Html方法,很XX的一个问题就是只能获取调用此方法的控制器下所有视图,不能跨控制器获取视图,有待优化
/// <summary>
/// 获取MVC视图Html
/// </summary>
/// <param name="context">控制器上下文</param>
/// <param name="viewName">视图名称</param>
/// <param name="param"></param>
/// <returns></returns>
public static string GetViewHtml(ControllerContext context, string viewName)
{
if (string.IsNullOrEmpty(viewName))
viewName = context.RouteData.GetRequiredString("action");
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw);
try
{
viewResult.View.Render(viewContext, sw);
}
catch (Exception ex)
{
throw;
} return sw.GetStringBuilder().ToString();
}
}
6、将pdf流输出至客户浏览器下载方法
/// <summary>
/// 将pdf文件流输出至浏览器下载
/// </summary>
/// <param name="pdfFile">PDF文件流</param>
public static void PdfDownload(byte[] pdfFile)
{
byte[] buffer = pdfFile;
Stream iStream = new MemoryStream(buffer);
try
{
int length;
long dataToRead;
string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";//保存的文件名称
dataToRead = iStream.Length;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = "application/pdf"; //文件类型
HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());//添加文件长度,进而显示进度
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(filename, Encoding.UTF8));
while (dataToRead > )
{
if (HttpContext.Current.Response.IsClientConnected)
{
length = buffer.Length;
HttpContext.Current.Response.OutputStream.Write(buffer, , length);
HttpContext.Current.Response.Flush();
buffer = new Byte[length];
dataToRead = dataToRead - length;
}
else
{
dataToRead = -;
}
}
}
catch (Exception ex)
{
HttpContext.Current.Response.Write("文件下载时出现错误!");
}
finally
{
if (iStream != null)
{
iStream.Close();
}
//结束响应,否则将导致网页内容被输出到文件,进而文件无法打开
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End(); }
}
7、MVC控制器下调用Demo(步骤4、6 方法封装至帮助类)
public class HomeController : Controller
{
//
// GET: /Home/ public ActionResult Index()
{
//从网址下载Html字符串(方法一)
string inpath = System.Web.HttpContext.Current.Server.MapPath("~/PDFTemplate/test.html");
string htmlText = HtmlToPdfHelper.GetWebContent(inpath);//此处调用步骤4方法 //获取MVC视图Html字符串(方法二)
//string htmlText = GetViewHtml(ControllerContext, "Test");//此处调用步骤5方法 //水印图片路径
string picPath = Server.MapPath("~/PDFTemplate/TemplateImg/authentication-iocn.png");
//html转pdf并加上水印
byte[] pdfFile = HtmlToPdfHelper.ConvertHtmlTextToPdf(htmlText, picPath, , , , );
//输出至客户端
HtmlToPdfHelper.PdfDownload(pdfFile);//此处调用步骤6方法 return View();
} public ActionResult Test()
{
return View();
} /// <summary>
/// 获取MVC视图Html
/// </summary>
/// <param name="context"></param>
/// <param name="viewName">视图名称</param>
/// <returns></returns>
public static string GetViewHtml(ControllerContext context, string viewName)
{
if (string.IsNullOrEmpty(viewName))
viewName = context.RouteData.GetRequiredString("action");
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData,
context.Controller.TempData, sw);
try
{
viewResult.View.Render(viewContext, sw);
}
catch (Exception ex)
{
throw;
} return sw.GetStringBuilder().ToString();
}
}
}
总结:我理解的解决思路是将html读取转换成字符串,之后再通过 itextsharp 转换成 pdf 比特流 传输至客户端或直接保存至服务器生成链接供用户下载。(新手上路,不妥之处,欢迎各位大神指教)
以上代码仅满足个人业务逻辑需求,如侵删,谢谢浏览。
asp.net MVC设计模式中使用iTextSharp实现html字符串生成PDF文件的更多相关文章
- 【初学者指南】在ASP.NET MVC 5中创建GridView
介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些 ...
- [转]在 ASP.NET MVC 4 中创建为移动设备优化的视图
原文链接 https://msdn.microsoft.com/zh-cn/magazine/dn296507.aspx 如果深入探讨有关编写移动设备网站的常识性考虑因素,会发现其中有一种内在矛盾. ...
- ASP.NET MVC 4中如何为不同的浏览器自适应布局和视图
在ASP.NET MVC 4中,可以很简单地实现针对不同的浏览器自适应布局和视图.这个得归功于MVC中的"约定甚于配置"的设计理念. 默认的自适应 MVC 4自动地为移动设备浏览器 ...
- 在ASP.NET MVC环境中使用加密与解密
在.NET Framework 4.5的NET框架中,在程序中加密与解密很方便.现在均学习ASP.NET MVC程序了,因此Insus.NET也在此写个学习的例子.在需要时可以参考与查阅. 写一个Ut ...
- 在 ASP.NET MVC 应用中使用 NInject 注入 ASMX 类型的 Web Service
这几天,有同学问到为什么在 ASP.NET MVC 应用中,无法在 .ASMX 中使用 NInject 进行注入. 现象 比如,我们定义了一个接口,然后定义了一个实现. public interfac ...
- 在 ASP.NET MVC 项目中使用 WebForm、 HTML
原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...
- C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...
- asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析
下面我用一个实例来和大家分享一下我的经验,asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析. using Newtonsoft.Json; usin ...
- 在已有的Asp.net MVC项目中引入Taurus.MVC
Taurus.MVC是一个优秀的框架,如果要应用到已有的Asp.net MVC项目中,需要修改一下. 1.前提约定: 走Taurus.MVC必须指定后缀.如.api 2.原项目修改如下: web.co ...
随机推荐
- CFGym 101158B(巨坑题)
前言:无话可说,看懂题意就没什么难度了. 题意:对于[0, 9999]区间内的每一个数b,通过输入的转换表,得到一个e值,把这个值添加到b的后面,得到一个五位数c.对于c的每一位,从0枚举到9,得到5 ...
- Docker系列06:Linux修改docker镜像和容器数据存储位置
指定镜像和容器存放路径的参数是--graph=/var/lib/docker,其默认存储位置为/var/lib/docker, Docker 的配置文件可以设置大部分的后台进程参数,在各个操作系统中的 ...
- 我对商业模式O2O的理解
过这个文章不是来吐槽项目经理多麽困难的,而且对商业模式的一点心得和讨论. 在这个公司,从项目建设上讲,老实说贡献不是很大,做项目经理团队带的不好,当然小创业公司本身资源真的非常有限,自己也特别累,有老 ...
- Hive常见问题汇总
参考资料: Hive常见问题汇总 啟動hive出錯,提示沒有權限 2015年04月02日 09:58:49 阅读数:31769 这里小编汇集,使用Hive时遇到的常见问题. 1,执行#hive命令进入 ...
- hadoop学习day3 mapreduce笔记
1.对于要处理的文件集合会根据设定大小将文件分块,每个文件分成多块,不是把所有文件合并再根据大小分块,每个文件的最后一块都可能比设定的大小要小 块大小128m a.txt 120m 1个块 b.txt ...
- MPI 集合通信函数 MPI_Scatterv(),MPI_Gatherv(),MPI_Allgatherv(),MPI_Alltoall(),MPI_Alltoallv(),MPI_Alltoallw()
▶ 函数 MPI_Scatterv() 和 MPI_Gatherv() .注意到函数 MPI_Scatter() 和 MPI_Gather() 只能向每个进程发送或接受相同个数的元素,如果希望各进程获 ...
- lamp。查看版本
[root@localhost ~]# php -vPHP 5.2.16 (cli) (built: Dec 17 2010 14:09:03) Copyright (c) 1997-2010 The ...
- Python实践练习:疯狂填词
题目 创建一个疯狂填词(Mad Libs)程序,它将读入文本文件,并让用户在该文本文件中出现 ADJECTIVE.NOUN.ADVERB 或 VERB 等单词的地方,加上他们自己的文本. 例如,一个文 ...
- Java 8 新特新 工具类 ZonedDateTime
类ZonedDateTime java.lang.Object继承 java.time.ZonedDateTime 所有实现的接口: Serializable,Comparable < Chro ...
- SystemColors 成员
名称 说明 ActiveBorder 获取 Color 结构,它是活动窗口边框的颜色. ActiveCaption 获取 Color 结构,它是活动窗口标题栏的背景色. ActiveCaptionTe ...