Itext7 HtmlConverter不显示gif
Posted
技术标签:
【中文标题】Itext7 HtmlConverter不显示gif【英文标题】:Itext7 HtmlConverter does not display gif 【发布时间】:2021-11-11 14:01:14 【问题描述】:我正在尝试将 html 转换为具有相对路径的图像标签的 pdf。
<IMG src="./ups_logo.gif" ALT="UPS Logo">
这是我从 API 获得的动态 HTML。
当我像这样使用 HTMLConverter 将其转换为 PDF 时:
string htmlString = "<!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\"><TITLE>UPS Package Tracking</TITLE></HEAD><BODY><TABLE width=500 border=0 cellSpacing=0 cellPadding=0><TR><TD rowspan=\"30\" Width=\"17\"> </TD><TD><TABLE cellSpacing=0 cellPadding=0 border=0 ><TR><TD align=\"left\" width=\"30\" > <IMG src=\"./ups_logo.gif\" ALT=\"UPS Logo\"></TD><TD><IMG src=\"./ups_banner.gif\" ALT=\"UPS Banner\" ></TD></TR></TABLE></TD></TR><TR><TD><TABLE cellSpacing=0 cellPadding=0 width=500 border=0 ><TR><TD colSpan=2 align=left><B>DELIVERY NOTIFICATION</B></TD><TD></TD></TR><TR><TD> </TD></TR><TR><TD colSpan=2>Dear Customer,</TD></TR><TR><TD> </TD></TR><TR><TD colSpan=3>This is in response to your request for delivery information concerning the shipment listed below.</TD></TR><TR><TD> </TD></TR><TR><TD align=right>Tracking Number: </TD><TD align=left>XX XXX XXX XX XXXX XXX X</TD></TR><TR><TD valign=top align=right><nobr> Reference Number(s): </nobr></TD><TD align=left><Table cellSpacing=0 cellPadding=0 width = 65%><TR><TD>XXXXXXXXXXXXXXXXX, XXXX, XXXXXXXXXXXXXXXXX, XXXXX5 </TD></TR></TABLE></TD></TR><TR><TD align=right>Service Type: </TD><TD align=left>UPS GROUND</TD></TR><TR><TD align=right>Package Weight: </TD><TD align=left>7.00 LBS</TD></TR><TR><TD align=right>Shipped or Billed on: </TD><TD align=left>Sep 01, 2021</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD align=right valign=top>Delivered on: </TD><TD align=left>Sep 07, 2021 3:10 P.M.</TD></TR><TR><TD align=right valign=top>Delivered to: </TD><TD align=left>York, NY, US, 11111</TD></TR><TR><TD align=right>Signed By: </TD><TD align=left>AngryOtter</TD></TR><TR><TD align=right>Location: </TD><TD align=left>Receiver</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD> </TD><TD> </TD></TR> <TR><TD colSpan=2>Thank you for giving us this opportunity to serve you.</TD></TR><TR><TD> </TD></TR> <TR><TD>Sincerely,</TD></TR> <TR><TD>United Parcel Service</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD colSpan=2>Tracking results provided by UPS: Sep 16, 2021 2:02 P.M. Eastern Time (USA)</TD></TR></TABLE></TD></TR></TABLE></BODY></HTML>";
byte[] pdfData;
using (var memoryStream = new MemoryStream())
ConverterProperties properties = new ConverterProperties();
properties.SetBaseUri("../img/");
HtmlConverter.ConvertToPdf(htmlString, memoryStream,properties);
pdfData = memoryStream.ToArray();
File.WriteAllBytes("c:\\test.pdf", pdfData);
其他一切都显示得很好,我生成了 PDF,所有信息都在那里,但图像没有显示。它也没有坏,只是不在那里。也不例外。图片的源文件目前在项目的解决方案级别。
文件结构:
Desktop
--TrackWSSample
--.sln
--.suo
--img(folder)
--ups_logo.gif
--TrackWSSample
--app.config
--package.config
--program.cs
编辑:我的请求/响应代码:
TrackService track = new TrackService();
TrackRequest tr = new TrackRequest();
UPSSecurity upss = new UPSSecurity();
UPSSecurityServiceAccessToken upssSvcAccessToken = new UPSSecurityServiceAccessToken();
upssSvcAccessToken.AccessLicenseNumber = "my_number";
upss.ServiceAccessToken = upssSvcAccessToken;
UPSSecurityUsernameToken upssUsrNameToken = new UPSSecurityUsernameToken();
upssUsrNameToken.Username = "userName";
upssUsrNameToken.Password = "Password";
upss.UsernameToken = upssUsrNameToken;
track.UPSSecurityValue = upss;
RequestType request = new RequestType();
string[] requestOption = "14" ;
request.RequestOption = requestOption;
tr.Request = request;
tr.InquiryNumber = "my_tracking_number";
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11; //This line will ensure the latest security protocol for consuming the web service call.
TrackResponse trackResponse = track.ProcessTrack(tr);
string s = trackResponse.Shipment[0].Package[0].Activity[0].Document[0].Content;
byte[] htmlBytes = Convert.FromBase64String(s);
string htmlString = Encoding.UTF8.GetString(htmlBytes);
感谢任何帮助
【问题讨论】:
@KJ 不,我什至硬编码了图像的绝对路径,仍然没有工作 @KJ gif 仍然不存在,即使我将 url 设置为"./img/"
。绝对不需要路径,因为 prod 环境将具有不同的路径。但是,当我做properties.SetBaseUri("C:/Users/User Name/Desktop/TrackWSSample/img");
时,即使这样也不起作用
能否添加发送/接收请求的代码以便我进行测试?显然,用通用数据替换您的用户名、密码和 AccessLicenseNumber。 (例如:my_username、my_password、my_access_license_number)。
@user9938 添加,和UPS提供的示例代码差别不大。
【参考方案1】:
根据pdfHTML: configuration options:
ConverterProperties: 通过各种方法重载,您可以 在前两个参数中指定某些输入参数类型,但是 总是有可选的第三个参数 ConverterProperties。这 参数包含允许用户使用的基本配置选项 以各种方式自定义输入数据的处理。我们现在将 详细说明这些选项,以便您可以配置您的 pdfHTML 代码 以获得最佳结果。
baseUri:如果 HTML 文件需要任何外部资源,例如 独立的 CSS 文件或图像文件,然后 pdfHTML 文件需要知道 这些在哪里。该位置可能是 本地文件系统或在线。
pdfHTML 将尝试使用合理的默认值,以防您不这样做 指定一个 baseUri。如果您使用字符串参数来传递您的 HTML, 那么默认值将是执行代码的文件夹。 如果您将 convertToPdf 的重载与 File 参数一起使用,它将 使用与输入文件相同的位置。
如果这些默认设置都不适合您,那么您需要 定义默认资源位置根。然后,在 HTML 文件将从该路径开始查找资源。它是 可以使用 ../ 语法在您的目录树中上 文件系统,但出于其他目的,指定的 URI 充当 用于确定路径的根文件夹。
先决条件:
下载/安装 NuGet 包itext7
下载/安装 NuGet 包itext7.pdfhtml
添加以下 using 语句:
using System;
using System.IO;
using iText.Html2pdf;
尝试以下方法:
注意:指定 HTML 文件名、PDF 文件名(另存为)和 baseUri(如果 HTML 文件包含图像或样式表等资源)
创建PDF
public static void CreatePdf(string htmlFilename, string pdfFilename, string baseUri = "")
byte[] pdfData;
if (!System.IO.File.Exists(htmlFilename))
throw new Exception("Error: '" + htmlFilename + "' doesn't exist.");
using (FileStream fs = new FileStream(htmlFilename, FileMode.Open, FileAccess.Read))
using (var memoryStream = new MemoryStream())
//when specifying HTML as a string and the HTML includes
//a resource that uses relative paths,
//it's necessary to specify the baseUri (path)
//create new instance
ConverterProperties properties = new ConverterProperties();
if (!String.IsNullOrEmpty(baseUri))
//set value
properties.SetBaseUri(baseUri);
else
//get folder name that HTML file exists in
string folderName = System.IO.Path.GetDirectoryName(htmlFilename);
//set value
properties.SetBaseUri(folderName);
//System.Diagnostics.Debug.WriteLine("BaseURI: " + properties.GetBaseUri());
//convert HTML to PDF
HtmlConverter.ConvertToPdf(fs, memoryStream, properties);
//save to byte[]
pdfData = memoryStream.ToArray();
File.WriteAllBytes(pdfFilename, pdfData);
public static void CreatePdfFromHtmlString(string htmlString, string pdfFilename, string baseUri)
byte[] pdfData;
using (var memoryStream = new MemoryStream())
//when specifying HTML as a string and the HTML includes
//a resource that uses relative paths,
//it's necessary to specify the baseUri (path)
//create new instance
ConverterProperties properties = new ConverterProperties();
//set value
properties.SetBaseUri(baseUri);
//convert HTML to PDF
HtmlConverter.ConvertToPdf(htmlString, memoryStream, properties);
//save to byte[]
pdfData = memoryStream.ToArray();
File.WriteAllBytes(pdfFilename, pdfData);
用法:将 HTML 指定为字符串
string htmlFilename = @"C:\Temp\default.html";
string folderName = System.IO.Path.GetDirectoryName(htmlFilename);
string html = System.IO.File.ReadAllText(htmlFilename);
string pdfFilename = @"C:\Temp\default.pdf";
//convert HTML to PDF and save to file
CreatePdfFromHtmlString(html, pdfFilename, folderName);
用法:指定 HTML 文件名
string htmlFilename = @"C:\Temp\default.html";
string pdfFilename = @"C:\Temp\default.pdf";
//convert HTML to PDF and save to file
CreatePdf(htmlFilename, pdfFilename);
更新:
以下是用于测试的 HTML 文件:
default.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>HTML Test</h2>
<div>
<IMG src="./ups_logo.gif" ALT="UPS Logo">
</div>
<p>
<div>
This is a test message
</div>
</body>
</html>
注意:名为“ups_logo.gif”的图像文件应与 HTML 文件位于同一文件夹中。
更新 2:
由于您似乎在从文件中获取徽标图像时遇到问题,请使用以下方法将从 UPS Developer Kit 下载的 .zip 文件中的徽标图像转换为 base64 字符串 - 您将在“Common”中找到徽标图像和 .zip 文件中的 General\Logos\LOGO_L.gif"。
ConvertImageToBase64String
private static string ConvertImageToBase64String(string filename)
string result = string.Empty;
using (System.Drawing.Image image = System.Drawing.Image.FromFile(filename))
using (System.IO.MemoryStream m = new System.IO.MemoryStream())
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
//convert byte[] to base64 string
result = Convert.ToBase64String(imageBytes);
return result;
注意:只需执行一次。不幸的是,base64 字符串太长,无法在此处发布。在下面的代码中,将 <logo image as base64 string>
替换为徽标图像的 base64 字符串。
如果尚未添加,请添加以下 using 语句:
using System;
using System.IO;
using iText.Html2pdf;
ImageSizeType
public enum ImageSizeType
Width,
Height
将以下方法添加到您的代码中:
public static byte[] GetUpsLogo(int newSizeWidthOrHeight, ImageSizeType sizeType)
byte[] imageBytes = null;
//ToDo: add logo image as base64 string
string upsLogoLBase64Str = <logo image as base64 string>;
//convert base64 string to byte[]
imageBytes = Convert.FromBase64String(upsLogoLBase64Str);
//resize image
imageBytes = ResizeImageMaintainingAspectRatio(imageBytes, newSizeWidthOrHeight, sizeType);
return imageBytes;
public static string GetUpsLogoAsBase64String(int newSizeWidthOrHeight, ImageSizeType sizeType)
string upsLogoBase64Str = string.Empty;
//get UPS logo
byte[] imageBytes = GetUpsLogo(newSizeWidthOrHeight, sizeType);
//convert to base64 string
upsLogoBase64Str = Convert.ToBase64String(imageBytes);
return upsLogoBase64Str;
public static byte[] ResizeImageMaintainingAspectRatio(byte[] imageBytes, int newSizeWidthOrHeight, ImageSizeType sizeType)
byte[] result = null;
//resize image
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
using (System.Drawing.Image img = System.Drawing.Image.FromStream(ms))
int sourceWidth = img.Width;
int sourceHeight = img.Height;
int newWidth = 0;
int newHeight = 0;
if (sizeType == ImageSizeType.Width)
//set value
newWidth = newSizeWidthOrHeight;
//calculate new height
newHeight = newSizeWidthOrHeight * sourceHeight / sourceWidth;
else
//set value
newHeight = newSizeWidthOrHeight;
//calculate new width
newWidth = newSizeWidthOrHeight * sourceWidth / sourceHeight;
using (System.Drawing.Bitmap b = new System.Drawing.Bitmap(img, new System.Drawing.Size(newWidth, newHeight)))
using (MemoryStream ms2 = new MemoryStream())
//b.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
b.Save(ms2, System.Drawing.Imaging.ImageFormat.Gif);
result = ms2.ToArray();
return result;
public static void SaveUpsLogo(string filename, int newSizeWidthOrHeight, ImageSizeType sizeType)
//get UPS logo
byte[] imageBytes = GetUpsLogo(newSizeWidthOrHeight, sizeType);
//save to file
System.IO.File.WriteAllBytes(filename, imageBytes);
如果使用“更新 2”中发布的代码,则以下代码可用于 CreatePdfFromHtmlString
,因为 HTML 将不再包含徽标图像的引用。我保留了上面的原始方法,因为它可能对遇到这篇文章的其他人有用。
CreatePdfFromHtmlString:
public static void CreatePdfFromHtmlString(string htmlString, string pdfFilename)
byte[] pdfData;
using (var memoryStream = new MemoryStream())
//when specifying HTML as a string and the HTML includes
//a resource that uses relative paths,
//it's necessary to specify the baseUri (path)
//use the overload that allows baseUri to be specified
//convert HTML to PDF
HtmlConverter.ConvertToPdf(htmlString, memoryStream);
//save to byte[]
pdfData = memoryStream.ToArray();
File.WriteAllBytes(pdfFilename, pdfData);
用法:
string html = "<!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\"><TITLE>UPS Package Tracking</TITLE></HEAD><BODY><TABLE width=500 border=0 cellSpacing=0 cellPadding=0><TR><TD rowspan=\"30\" Width=\"17\"> </TD><TD><TABLE cellSpacing=0 cellPadding=0 border=0 ><TR><TD align=\"left\" width=\"30\" > <IMG src=\"./ups_logo.gif\" ALT=\"UPS Logo\"></TD><TD><IMG src=\"./ups_banner.gif\" ALT=\"UPS Banner\" ></TD></TR></TABLE></TD></TR><TR><TD><TABLE cellSpacing=0 cellPadding=0 width=500 border=0 ><TR><TD colSpan=2 align=left><B>DELIVERY NOTIFICATION</B></TD><TD></TD></TR><TR><TD> </TD></TR><TR><TD colSpan=2>Dear Customer,</TD></TR><TR><TD> </TD></TR><TR><TD colSpan=3>This is in response to your request for delivery information concerning the shipment listed below.</TD></TR><TR><TD> </TD></TR><TR><TD align=right>Tracking Number: </TD><TD align=left>XX XXX XXX XX XXXX XXX X</TD></TR><TR><TD valign=top align=right><nobr> Reference Number(s): </nobr></TD><TD align=left><Table cellSpacing=0 cellPadding=0 width = 65%><TR><TD>XXXXXXXXXXXXXXXXX, XXXX, XXXXXXXXXXXXXXXXX, XXXXX5 </TD></TR></TABLE></TD></TR><TR><TD align=right>Service Type: </TD><TD align=left>UPS GROUND</TD></TR><TR><TD align=right>Package Weight: </TD><TD align=left>7.00 LBS</TD></TR><TR><TD align=right>Shipped or Billed on: </TD><TD align=left>Sep 01, 2021</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD align=right valign=top>Delivered on: </TD><TD align=left>Sep 07, 2021 3:10 P.M.</TD></TR><TR><TD align=right valign=top>Delivered to: </TD><TD align=left>York, NY, US, 11111</TD></TR><TR><TD align=right>Signed By: </TD><TD align=left>AngryOtter</TD></TR><TR><TD align=right>Location: </TD><TD align=left>Receiver</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD> </TD><TD> </TD></TR> <TR><TD colSpan=2>Thank you for giving us this opportunity to serve you.</TD></TR><TR><TD> </TD></TR> <TR><TD>Sincerely,</TD></TR> <TR><TD>United Parcel Service</TD></TR><TR><TD> </TD><TD> </TD></TR><TR><TD colSpan=2>Tracking results provided by UPS: Sep 16, 2021 2:02 P.M. Eastern Time (USA)</TD></TR></TABLE></TD></TR></TABLE></BODY></HTML>";
string upsLogoBase64Str = GetUpsLogoAsBase64String(100, ImageSizeType.Height);
string base64SrcStr = "data:image/gif;base64, " + upsLogoBase64Str;
html = html.Replace("./ups_logo.gif", base64SrcStr);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "PDF File (*.pdf)|*.pdf";
//prompt for filename to save PDF file as
if (sfd.ShowDialog() == DialogResult.OK)
CreatePdfFromHtmlString(html, sfd.FileName);
资源:
Chapter 1: Hello HTML to PDF how to set baseuri in converterproperties in itext7 html to pdf converter How to display Base64 images in HTML c# Image resizing to different size while preserving aspect ratio【讨论】:
非常感谢您详细的撰写。不幸的是,我尝试使用 ConverterProperty 使用绝对路径和相对路径,但它仍然无法正常工作。 gif仍然丢失。我已经上传了我使用的 html 以及文件结构。If you use a String parameter to pass your HTML, then the default value will be the folder where the code is executed.
,不使用ConverterProperty,好像还是会在当前目录中查找资源文件,那我也不知道为什么我原来的方法也不起作用。跨度>
@AngryOtter:上面的代码使用带有 .gif 文件的 HTML 文件进行了测试。尝试创建以下文件夹:C:\Temp
并将 HTML 文件和图像文件放在 C:\Temp
我从 UPS API 获得了这个 HTML 字符串作为 SOAP 响应的一部分,因此它不会创建文件。相反,它需要直接从字符串转换为 PDF。
@AngryOtter:看起来 UPS 有很多 API。你用的是哪一个?以上是关于Itext7 HtmlConverter不显示gif的主要内容,如果未能解决你的问题,请参考以下文章
当我在属性内容中使用 CSS3 函数 target-counter 时,iText7 不起作用