Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员
查看: 13|回复: 0

【译】Asp.net mvc 使用ITextSharp PDF to HTML (解决img标签问题)

[复制链接]
  • TA的每日心情
    奋斗
    昨天 19:16
  • 签到天数: 66 天

    [LV.6]常住居民II

    1348

    主题

    1348

    帖子

    3万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32858
    发表于 2021-6-10 19:19:48 | 显示全部楼层 |阅读模式

    前言:因项目需求,需要将HTML代码转成PDF。大致上已经实现了,可以是发现使用ITextSharp(我现在的版本是5.5.9)的时候,img标签中的src只能跟绝对路径。

    在百度上找了一个上午,有一点关联的解决方案都没有。最后去谷歌求助,终于找到了。

    这是原文:http://www.am22tech.com/html-to-pdf/(可能需要翻墙)

    这是我总结后做的一个例子(使用的是第二个解决方法):http://files.cnblogs.com/files/zuochengsi-9/HTML%E8%BD%ACPDF.zip

    不懂的也可以参考我的这篇博客:http://www.cnblogs.com/zuochengsi-9/p/5483808.html

     

    ------------------------------------------------------------------

    正文:

    我正在到处寻找完美的例子,可是没有一个能完美的解决我的需求。我的需求非常简单,如下:

    创建一个PDF文档从一个HTML页面。这个HTML里的代码包含的了img标签,同时用的相对路径。

    我找到了有价值的信息从这几个地方http://kuujinbo.info/iTextSharp/tableWithImageToPdf.aspx

    http://hamang.net/2008/08/14/html-to-pdf-in-net/

    最终,可以用下面的asp.net代码解决了我的问题。我希望这也能帮助到你!

    必要条件:

    Download and copy iTextSharp.dll 我的版本是5.1.1

    问题和解决方案:

    这个新的ITextSharp库,对于HTML代码转PDF已经做的很好了。可是有个主要的缺陷,图片的URL映射只能是绝对路径。

    不然HTMLworlker类就会抛异常,如果你用的相对路径。

    这里有两个解决方法对于这个问题:

    1、用IImageProvider 接口取出所有的图片从HTML代码中,然后再"paste"PDF中。

     但是HTML代码中对img修饰的style,例如height和width都不会保留下来。

    2、解析HTML代码,同时用绝对的URL替换相对的URL在写入PDF文件之前。

    这个方法会保存HTML代码中对与<img>设置的height和width。当然这个方法更好。

    不过我还是提供两种解决方案让你自己去选择。

    基本的准备:

    添加一个新的page在你的代码中

    PostToPDF_AM22.aspx

    PostToPDF_AM22.aspx.cs

    方法1:

     

    using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.UI;
        using System.Web.UI.WebControls;
    
        //HTML to PDF 的引用
        using iTextSharp.text;
        using iTextSharp.text.html;
        using iTextSharp.text.pdf;
        using iTextSharp.text.xml;
        using iTextSharp.text.html.simpleparser;
        using System.IO;
        using System.util;
        using System.Text.RegularExpressions;
        //For converting HTML TO PDF- END
    
        public partial class PostToPDF_AM22 : System.Web.UI.Page
        {
        protected void Page_Load(object sender, EventArgs e)
        {
        //Get the HTML code from your database or whereever you have stored it and store
        //it in HTMLCode variable.
        string HTMLCode = string.Empty;
        ConvertHTMLToPDF(HTMLCode);
        }
        protected void ConvertHTMLToPDF(string HTMLCode)
        {
        HttpContext context = HttpContext.Current;
    
        //Render PlaceHolder to temporary stream
        System.IO.StringWriter stringWrite = new StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
    
        StringReader reader = new StringReader(HTMLCode);
    
        //Create PDF document
        Document doc = new Document(PageSize.A4);
        HTMLWorker parser = new HTMLWorker(doc);
        PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("~") + "/App_Data/HTMLToPDF.pdf",
    
        FileMode.Create));
        doc.Open();
    
        /********************************************************************************/
        var interfaceProps = new Dictionary<string, Object>();
        var ih = new ImageHander() { BaseUri = Request.Url.ToString() };
    
        interfaceProps.Add(HTMLWorker.IMG_PROVIDER, ih);
    
        foreach (IElement element in HTMLWorker.ParseToList(
        new StringReader(HTMLCode), null))
        {
        doc.Add(element);
        }
        doc.Close();
        Response.End();
    
        /********************************************************************************/
    
        }
    
        //handle Image relative and absolute URL's
        public class ImageHander : IImageProvider
        {
        public string BaseUri;
        public iTextSharp.text.Image GetImage(string src,
        IDictionary<string, string> h,
        ChainedProperties cprops,
        IDocListener doc)
        {
        string imgPath = string.Empty;
    
        if (src.ToLower().Contains("http://") == false)
        {
        imgPath = HttpContext.Current.Request.Url.Scheme + "://" +
    
        HttpContext.Current.Request.Url.Authority + src;
        }
        else
        {
        imgPath = src;
        }
    
        return iTextSharp.text.Image.GetInstance(imgPath);
        }
        }
        }

     

    方法2:

    using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.UI;
        using System.Web.UI.WebControls;
    
        //For converting HTML TO PDF- START
        using iTextSharp.text;
        using iTextSharp.text.html;
        using iTextSharp.text.pdf;
        using iTextSharp.text.xml;
        using iTextSharp.text.html.simpleparser;
        using System.IO;
        using System.util;
        using System.Text.RegularExpressions;
        //For converting HTML TO PDF- END
    
        public partial class PostToPDF_AM22 : System.Web.UI.Page
        {
        protected void Page_Load(object sender, EventArgs e)
        {
        //Get the HTML code from your database or whereever you have stored it and store
        //it in HTMLCode variable.
        string HTMLCode = string.Empty;
        ConvertHTMLToPDF(HTMLCode);
        }
        protected void ConvertHTMLToPDF(string HTMLCode)
        {
        HttpContext context = HttpContext.Current;
    
        //Render PlaceHolder to temporary stream
        System.IO.StringWriter stringWrite = new StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
    
        /********************************************************************************/
        //Try adding source strings for each image in content
        string tempPostContent = getImage(HTMLCode);
        /*********************************************************************************/
    
        StringReader reader = new StringReader(tempPostContent);
    
        //Create PDF document
        Document doc = new Document(PageSize.A4);
        HTMLWorker parser = new HTMLWorker(doc);
        PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("~") + "/App_Data/HTMLToPDF.pdf",
    
        FileMode.Create));
        doc.Open();
    
        try
        {
        //Parse Html and dump the result in PDF file
        parser.Parse(reader);
        }
        catch (Exception ex)
        {
        //Display parser errors in PDF.
        Paragraph paragraph = new Paragraph("Error!" + ex.Message);
        Chunk text = paragraph.Chunks[0] as Chunk;
        if (text != null)
        {
        text.Font.Color = BaseColor.RED;
        }
        doc.Add(paragraph);
        }
        finally
        {
        doc.Close();
        }
        }
    
        public string getImage(string input)
        {
        if (input == null)
        return string.Empty;
        string tempInput = input;
        string pattern = @"<img(.|\n)+?>";
        string src = string.Empty;
        HttpContext context = HttpContext.Current;
    
        //Change the relative URL's to absolute URL's for an image, if any in the HTML code.
        foreach (Match m in Regex.Matches(input, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline |
    
        RegexOptions.RightToLeft))
        {
        if (m.Success)
        {
        string tempM = m.Value;
        string pattern1 = "src=[\'|\"](.+?)[\'|\"]";
        Regex reImg = new Regex(pattern1, RegexOptions.IgnoreCase | RegexOptions.Multiline);
        Match mImg = reImg.Match(m.Value);
    
        if (mImg.Success)
        {
        src = mImg.Value.ToLower().Replace("src=", "").Replace("\"", "");
    
        if (src.ToLower().Contains("http://") == false)
        {
        //Insert new URL in img tag
        src = "src=\"" + context.Request.Url.Scheme + "://" +
        context.Request.Url.Authority + src + "\"";
        try
        {
        tempM = tempM.Remove(mImg.Index, mImg.Length);
        tempM = tempM.Insert(mImg.Index, src);
    
        //insert new url img tag in whole html code
        tempInput = tempInput.Remove(m.Index, m.Length);
        tempInput = tempInput.Insert(m.Index, tempM);
        }
        catch (Exception e)
        {
    
        }
        }
        }
        }
        }
        return tempInput;
        }
    
        string getSrc(string input)
        {
        string pattern = "src=[\'|\"](.+?)[\'|\"]";
        System.Text.RegularExpressions.Regex reImg = new System.Text.RegularExpressions.Regex(pattern,
        System.Text.RegularExpressions.RegexOptions.IgnoreCase |
    
        System.Text.RegularExpressions.RegexOptions.Multiline);
        System.Text.RegularExpressions.Match mImg = reImg.Match(input);
        if (mImg.Success)
        {
        return mImg.Value.Replace("src=", "").Replace("\"", ""); ;
        }
    
        return string.Empty;
        }
        }

    说明:

    上面的两种方案,都有一个方法ConvertHTMLToPDF,对于得到的HTML代码的格式是有要求的,具体可以去ITextSharp官网看看。

    最后结果存储的一个PDF文档的名字叫HTMLToPDF.pdf在你的web站点的App_Data文件夹里

    记得,你需要写代码去拿到HTML代码从你的数据库中或者其他文件里在上面的Page_Load事件中。

    通过HTML代码转换函数,它将为您创建PDF文件。

    如果你面临任何问题,写在评论中,我会尽力帮助你 。

    ——————————————————————————————————————

    初次翻译,就直接原样翻译了。但通过这次就感觉看英文资料没有以前那种抗拒感了。果然还是有尝试,就会有收获!

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2021-6-22 22:05 , Processed in 0.060984 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表