从 C# 中的 iTextSharp 库将超链接导出到 pdf 文件
Export Hyperlink to pdf file from iTextSharp library in c#
我在使用 iTextSharp Library.
在 c# asp net 中导出一个 GridView 的 pdf 文件时遇到问题
在最后一列中,我预期是 Hyperlink,但在输出 pdf 中,我截断了 link 和一个不存在的连接,该连接响应错误 "page not found"。
请检查附件图片和代码c#。
有人知道我该如何解决这个问题吗?
提前致谢。
<asp:TemplateField HeaderText="hlKvm" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:HyperLink ID="hlKvm" runat="server" NavigateUrl='<%# Eval("Kvm").ToString() %>'
ImageUrl='<%#(String.IsNullOrEmpty(Eval("Kvm").ToString()) ? "/mac/Images/TRKO8.png" : "/Images/download.gif")%>'
ToolTip='<%#(String.IsNullOrEmpty(Eval("Kvm").ToString()) ? "" : "")%>'
Target="_blank" BorderStyle="None" ForeColor="Transparent">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
编辑 #1
这是Anchor方法的代码,请查看附图和下面的代码。
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = cellText.ToString();
table.AddCell(anchor);
编辑#2
如果尝试您的选项 1,输出为:
如果尝试您的选项 2,输出为:
Invalid URI: The URI is empty.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UriFormatException: Invalid URI: The URI is empty.
Source Error:
Line 772: iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Line 773: Chunk cImage = new Chunk(image, 0, 0, false);
Line 774: cImage.SetAction(new PdfAction(new Uri(cellText.ToString())));
Line 775: table.AddCell(new Phrase(cImage));
Line 776:
如果尝试您的 选项 2 并选中 cellText 为空,则输出为:
但是图像没有与 gridview 对齐...
您目前拥有此代码:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = cellText.ToString();
table.AddCell(anchor);
在 PdfPCell
的上下文中使用 Anchor
在旧版本的 iTextSharp 中不起作用。我认为这在很久以前就已修复。
但是,有一些替代方法可以达到相同的结果:
选项 1: 使用 SetAction
而不是 Anchor
:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
cImage.SetAction(new PdfAction(new Uri(cellText.ToString())));
table.AddCell(new Phrase(cImage));
PdfAction
需要一个 URL 并且 SetAction
将创建一个 link 注释来打开那个 URL.
选项 2: 使图像可点击:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Annotation annotation = new Annotation(0, 0, 0, 0, cellText);
image.Annotation = annotation;
table.AddCell(image);
可能还有其他选择,但请先尝试这两个选项,然后告诉我它们是否适合您。
更新#1:(对应于您的编辑#2,第二部分)
如果您尝试创建 PdfPCell
:
会怎样
PdfPCell cell = new PdfPCell(image, true);
table.AddCell(cell);
现在,image
对象将被缩放以使其正确适合单元格。
更新#2:(对应于您的编辑#2,第一部分)
这不是 iText 异常:
Invalid URI: The URI is empty.
这个问题可能是由cellText.ToString()
的值引起的。如果这不是有效的 URL(例如因为它是空的),那么您会得到一个异常。
概念验证
我写了一个概念证明,希望我能让你相信我说的是真的,希望其他读者在我说 iText 工作正常时相信我(而不是在你的说法正好相反)。
这是我的例子:ImagesLinksTable
这是生成的 PDF:images_links_table.pdf
在这个例子中,我使用了三种不同的技术。他们都有效:
技术 1: 使用 Anchor
:
Image img = Image.getInstance(IMG);
Chunk c = new Chunk(img, 0, 0, true);
Anchor anchor = new Anchor(c);
anchor.setReference("http://lowagie.com/");
table.addCell(anchor);
我创建了一个 Image
,我将它包装成一个 Chunk
,然后我在一个 Anchor
中使用了这个 Chunk
。我将 Anchor
添加到 table。这没有任何问题。
技术 2: 使用 setAction()
:
Chunk c2 = new Chunk(img, 0, 0, true);
c2.setAction(new PdfAction("http://itextpdf.com"));
table.addCell(new Phrase(c2));
在这种情况下,我们不使用 Anchor
,但我将 link 定义为一个动作。为什么要创建一个新的 Chunk
对象?如果我像以前一样使用相同的 Chunk
,那么我只能使用一个 URL 作为那个 Chunk
.
技巧三:
Image img2 = Image.getInstance(IMG);
Annotation a = new Annotation(0, 0, 0, 0, "http://lowagie.com/bio");
img2.setAnnotation(a);
table.addCell(img2);
在这种情况下,我在图像级别定义了link,但在这里我还必须创建一个新图像。如果我重新使用之前使用的图像,那么所有图像都会指向相同的 link.
这是我的 PDF 的样子:
如您所见,图像非常适合单元格。您可以轻松调整代码以更改 Image
and/or 的大小,以确保图像缩放(或不缩放)以匹配单元格的大小。
我的示例是用 Java 编写的,但是如果您使用 iTextSharp 端口并将我的示例移植到 C#,您将得到相同的结果。
我在使用 iTextSharp Library.
在 c# asp net 中导出一个 GridView 的 pdf 文件时遇到问题在最后一列中,我预期是 Hyperlink,但在输出 pdf 中,我截断了 link 和一个不存在的连接,该连接响应错误 "page not found"。
请检查附件图片和代码c#。
有人知道我该如何解决这个问题吗?
提前致谢。
<asp:TemplateField HeaderText="hlKvm" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:HyperLink ID="hlKvm" runat="server" NavigateUrl='<%# Eval("Kvm").ToString() %>'
ImageUrl='<%#(String.IsNullOrEmpty(Eval("Kvm").ToString()) ? "/mac/Images/TRKO8.png" : "/Images/download.gif")%>'
ToolTip='<%#(String.IsNullOrEmpty(Eval("Kvm").ToString()) ? "" : "")%>'
Target="_blank" BorderStyle="None" ForeColor="Transparent">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
编辑 #1
这是Anchor方法的代码,请查看附图和下面的代码。
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = cellText.ToString();
table.AddCell(anchor);
编辑#2
如果尝试您的选项 1,输出为:
如果尝试您的选项 2,输出为:
Invalid URI: The URI is empty.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UriFormatException: Invalid URI: The URI is empty.
Source Error:
Line 772: iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Line 773: Chunk cImage = new Chunk(image, 0, 0, false);
Line 774: cImage.SetAction(new PdfAction(new Uri(cellText.ToString())));
Line 775: table.AddCell(new Phrase(cImage));
Line 776:
如果尝试您的 选项 2 并选中 cellText 为空,则输出为:
但是图像没有与 gridview 对齐...
您目前拥有此代码:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = cellText.ToString();
table.AddCell(anchor);
在 PdfPCell
的上下文中使用 Anchor
在旧版本的 iTextSharp 中不起作用。我认为这在很久以前就已修复。
但是,有一些替代方法可以达到相同的结果:
选项 1: 使用 SetAction
而不是 Anchor
:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Chunk cImage = new Chunk(image, 0, 0, false);
cImage.SetAction(new PdfAction(new Uri(cellText.ToString())));
table.AddCell(new Phrase(cImage));
PdfAction
需要一个 URL 并且 SetAction
将创建一个 link 注释来打开那个 URL.
选项 2: 使图像可点击:
cellText = (gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).NavigateUrl;
string imagePath = Server.MapPath((gvProducts.Rows[rowIndex].Cells[16].FindControl("hlKvm") as HyperLink).ImageUrl);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imagePath);
Annotation annotation = new Annotation(0, 0, 0, 0, cellText);
image.Annotation = annotation;
table.AddCell(image);
可能还有其他选择,但请先尝试这两个选项,然后告诉我它们是否适合您。
更新#1:(对应于您的编辑#2,第二部分)
如果您尝试创建 PdfPCell
:
PdfPCell cell = new PdfPCell(image, true);
table.AddCell(cell);
现在,image
对象将被缩放以使其正确适合单元格。
更新#2:(对应于您的编辑#2,第一部分)
这不是 iText 异常:
Invalid URI: The URI is empty.
这个问题可能是由cellText.ToString()
的值引起的。如果这不是有效的 URL(例如因为它是空的),那么您会得到一个异常。
概念验证
我写了一个概念证明,希望我能让你相信我说的是真的,希望其他读者在我说 iText 工作正常时相信我(而不是在你的说法正好相反)。
这是我的例子:ImagesLinksTable
这是生成的 PDF:images_links_table.pdf
在这个例子中,我使用了三种不同的技术。他们都有效:
技术 1: 使用 Anchor
:
Image img = Image.getInstance(IMG);
Chunk c = new Chunk(img, 0, 0, true);
Anchor anchor = new Anchor(c);
anchor.setReference("http://lowagie.com/");
table.addCell(anchor);
我创建了一个 Image
,我将它包装成一个 Chunk
,然后我在一个 Anchor
中使用了这个 Chunk
。我将 Anchor
添加到 table。这没有任何问题。
技术 2: 使用 setAction()
:
Chunk c2 = new Chunk(img, 0, 0, true);
c2.setAction(new PdfAction("http://itextpdf.com"));
table.addCell(new Phrase(c2));
在这种情况下,我们不使用 Anchor
,但我将 link 定义为一个动作。为什么要创建一个新的 Chunk
对象?如果我像以前一样使用相同的 Chunk
,那么我只能使用一个 URL 作为那个 Chunk
.
技巧三:
Image img2 = Image.getInstance(IMG);
Annotation a = new Annotation(0, 0, 0, 0, "http://lowagie.com/bio");
img2.setAnnotation(a);
table.addCell(img2);
在这种情况下,我在图像级别定义了link,但在这里我还必须创建一个新图像。如果我重新使用之前使用的图像,那么所有图像都会指向相同的 link.
这是我的 PDF 的样子:
如您所见,图像非常适合单元格。您可以轻松调整代码以更改 Image
and/or 的大小,以确保图像缩放(或不缩放)以匹配单元格的大小。
我的示例是用 Java 编写的,但是如果您使用 iTextSharp 端口并将我的示例移植到 C#,您将得到相同的结果。