【问题标题】:Images don't display in PDF图像不显示在 PDF 中
【发布时间】:2017-06-03 11:53:04
【问题描述】:

我有一个通过 asp.net 呈现的相当简单的 HTML 页面。通过 HtmlRenderer.PdfSharp 运行 PDF 后,它看起来很漂亮,除了图像没有出现。即使网页本身确实正确显示了图像,也只是 PDF 中缺失图像的红色 X。

这是我的 HtmlRenderer.PdfSharp 代码:

public void BuildPDF( string url, string pdfPath ) {
   string html = GetHTML(url);
   Byte[] res = null;
   using( MemoryStream ms = new MemoryStream() ) {
      using( FileStream file = new FileStream(pdfPath, FileMode.Create, FileAccess.Write) ) {
         byte[] bytes = new byte[ms.Length];
         var pdf = TheArtOfDev.HtmlRenderer.PdfSharp.PdfGenerator.GeneratePdf(html, PdfSharp.PageSize.A4);
         pdf.Save(ms);
         res = ms.ToArray();
         file.Write(res, 0, res.Length);
         ms.Close();
      }
   }
}

private string GetHTML(string url) {
   string html = string.Empty;
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
   request.AutomaticDecompression = DecompressionMethods.GZip;

   using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() )
   using( Stream stream = response.GetResponseStream() )
   using( StreamReader reader = new StreamReader(stream) ) {
      html = reader.ReadToEnd();
   }

   return html;
}

这里是不在 PDF 中呈现的 img HTML:<img src="images/ChartImg.png" />

我该如何解决这个问题?

【问题讨论】:

    标签: html html-renderer


    【解决方案1】:

    使用图像的绝对路径。

    <img src="http://example.org/images/ChartImg.png" />
    

    您可以先解析 html 并进行字符串替换,然后再将其传递给 pdf 转换器。

    【讨论】:

      【解决方案2】:

      代码如下:

      var pdf = PdfGenerator.GeneratePdf(Html, PageSize.A4, 20, null, OnStylesheetLoad, OnImageLoadPdfSharp);
      ... ...
      public static void OnImageLoadPdfSharp(object sender, HtmlImageLoadEventArgs e)
      {
          var url = e.Src;
          if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
          {
              var ImgFilePath = System.Web.HttpContext.Current.Server.MapPath(url);
              if (XImage.ExistsFile(ImgFilePath))
                  e.Callback(XImage.FromFile(ImgFilePath));
              var ImgFilePath2 = System.Web.HttpContext.Current.Server.MapPath(url);
              if (XImage.ExistsFile(ImgFilePath2))
                  e.Callback(XImage.FromFile(ImgFilePath2));
          }
          else
          {
              using (var client = new WebClient())
              {
                  using (var stream = new MemoryStream(client.DownloadData(url)))
                  {
                      e.Callback(XImage.FromStream(stream));
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        最好为此使用图像分辨率回调:

        var pdf = PdfGenerator.GeneratePdf(html, pdfConfig, imageLoad: OnImageLoad);
        
        // snip
        
        private void OnImageLoad(object sender, HtmlImageLoadEventArgs e)
        {
            using (var client = new WebClient())
            {
                var url = e.Src;
                if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
                {
                    url = Properties.Settings.Default.BaseUrl.TrimEnd('/') + e.Src;
                }
                using (var stream = new MemoryStream(client.DownloadData(url)))
                {
                    e.Callback(XImage.FromStream(stream));
                }
            }
        }
        

        【讨论】:

          【解决方案4】:

          我迟到了你的问题,但也许这会帮助别人。

          我使用了绝对网址,它们是正确的。当我在浏览器中打开 html 文件时,图像已正确加载。

          但是,在我将此 html 转换为 pdf 后,它们没有加载。所以我尝试使用@ohjo 建议的图像分辨率回调。这里发生异常:一个现有的连接被远程主机强行关闭。

          我能够解决这个问题,但又添加了一行将 SecurityProtocol 设置为该解决方案:

          var pdf = PdfGenerator.GeneratePdf(Html, PageSize.A4, 20, null, OnStylesheetLoad, OnImageLoadPdfSharp);
          ... ...
          public static void OnImageLoadPdfSharp(object sender, HtmlImageLoadEventArgs e)
          {
              var url = e.Src;
              if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
              {
                  var ImgFilePath = System.Web.HttpContext.Current.Server.MapPath(url);
                  if (XImage.ExistsFile(ImgFilePath))
                      e.Callback(XImage.FromFile(ImgFilePath));
                  var ImgFilePath2 = System.Web.HttpContext.Current.Server.MapPath(url);
                  if (XImage.ExistsFile(ImgFilePath2))
                      e.Callback(XImage.FromFile(ImgFilePath2));
              }
              else
              {
                  using (var client = new WebClient())
                  {
                      ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                      using (var stream = new MemoryStream(client.DownloadData(url)))
                      {
                          e.Callback(XImage.FromStream(stream));
                      }
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-02-22
            • 2017-02-08
            • 2018-01-24
            • 1970-01-01
            • 2021-10-11
            • 2019-01-18
            • 1970-01-01
            相关资源
            最近更新 更多