iTextSharp HTMLWorker ParseHTML Tablestyle和PDFStamper

您好我已成功使用HTMLWorker使用asp.NET / C#转换gridview。

(1)我已经对结果表应用了一些有限的样式,但是无法看到如何将tablestyle应用于实例网格线或应用其他格式样式,例如特定列的大列宽。 (2)我实际上想把这个文本放到一个包含徽标等的预先存在的模板上。我之前使用过PDF Stamper但是看不出我如何同时使用PDFStamper和HTMLWorker。 HTMLWorker需要一个实现iDocListener的Document ……但这似乎与使用PDFStamper兼容。 我想我正在寻找的是一种创建PDFStamper,写标题等的方法,然后从网格中添加解析的HTML。 另一个问题是解析的内容不与页面上的其他内容交互。 例如,下面我向页面添加一个标题块。 而不是从它下面开始,解析的HTML写在顶部。 如何将解析的HTML内容与PDF文档中的其余内容进行放置/交互?

在此先感谢Rob

这是我已经拥有的代码

Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 30f, 0f); HTMLWorker htmlWorker = new HTMLWorker(pdfDoc); StyleSheet styles = new StyleSheet(); styles.LoadTagStyle("th", "size", "12px"); styles.LoadTagStyle("th", "face", "helvetica"); styles.LoadTagStyle("span", "size", "10px"); styles.LoadTagStyle("span", "face", "helvetica"); styles.LoadTagStyle("td", "size", "10px"); styles.LoadTagStyle("td", "face", "helvetica"); htmlWorker.SetStyleSheet(styles); PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream); pdfDoc.Open(); //Title - but this gets obsured by data, doesnt move it down Font font = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD); Chunk chunk = new Chunk(title, font); pdfDoc.Add(chunk); //Body htmlWorker.Parse(sr); 

让我先给你一些链接,以便在有机会时查看:

  1. ItextSharp支持HTML和CSS
  2. 如何在使用itextsharp将html传递给pdf时应用字体属性

这些答案会更深入地了解正在发生的事情,我建议您在有机会时阅读它们。 具体来说,第二个将告诉你为什么你需要使用pt而不是px

为了回答您的第一个问题,让我向您展示使用HTMLWorker类的不同方法。 这个类有一个名为ParseToList的静态方法,它将HTML转换为List 。 该列表中的对象都是HTML的iTextSharp特定版本。 通常你会对它们做一个foreach ,只是将它们添加到文档中,但你可以在添加之前修改它们,这是你想要做的。 下面是采用静态字符串的代码并执行此操作:

 string file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf"); using (FileStream fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.LETTER)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); //Our HTML string html = "
First NameLast Name
ChrisHaas
"; //ParseToList requires a StreamReader instead of just a string so just wrap it using (StringReader sr = new StringReader(html)) { //Create a style sheet StyleSheet styles = new StyleSheet(); //...styles omitted for brevity //Convert our HTML to iTextSharp elements List elements = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles); //Loop through each element (in this case there's actually just one PdfPTable) foreach (IElement el in elements) { //If the element is a PdfPTable if (el is PdfPTable) { //Cast it PdfPTable tt = (PdfPTable)el; //Change the widths, these are relative width by the way tt.SetWidths(new float[] { 75, 25 }); } //Add the element to the document doc.Add(el); } } doc.Close(); } } }

希望您可以看到,一旦您获得原始PdfPTable访问权限,您可以根据需要进行调整。

要回答第二个问题,如果要将正常的ParagraphChunk对象与PdfStamper一起使用,则需要使用PdfContentByte对象。 您可以通过两种方式从压模中获取此信息,方法是要求位于现有内容“上方”的那个, stamper.GetOverContent(int)或位于“现有内容”下方的那个, stamper.GetUnderContent(int) 。 两个版本都使用一个参数来说明要使用的页面。 一旦有了PdfContentByte ,就可以创建一个绑定到它的ColumnText对象,并使用该对象的AddElement()方法添加常规元素。 在执行此操作之前(这将回答您的第三个问题),您将需要创建至少一个“列”。 当我这样做时,我通常创建一个基本上覆盖整个页面的。 (这部分可能听起来很奇怪,但我们基本上是制作单行,单列表格单元格来添加我们的对象。)

下面是一个完整的C#2010 WinForms应用程序,目标是iTextSharp 5.1.1.0,它展示了上述所有内容。 首先,它在桌面上创建一个通用PDF。 然后它创建一个基于第一个文档的第二个文档,添加一个段落,然后添加一些HTML。 如有任何问题,请参阅代码中的注释。

 using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using iTextSharp.text; using iTextSharp.text.html.simpleparser; using iTextSharp.text.pdf; using System.IO; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //The two files that we are creating string file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf"); string file2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File2.pdf"); //Create a base file to write on top of using (FileStream fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.LETTER)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); doc.Add(new Paragraph("Hello world")); doc.Close(); } } } //Bind a reader to our first document PdfReader reader = new PdfReader(file1); //Create our second document using (FileStream fs = new FileStream(file2, FileMode.Create, FileAccess.Write, FileShare.None)) { using (PdfStamper stamper = new PdfStamper(reader, fs)) { StyleSheet styles = new StyleSheet(); //...styles omitted for brevity //Our HTML string html = "
First NameLast Name
ChrisHaas
"; //ParseToList requires a StreamReader instead of just a string so just wrap it using (StringReader sr = new StringReader(html)) { //Get our raw PdfContentByte object letting us draw "above" existing content PdfContentByte cb = stamper.GetOverContent(1); //Create a new ColumnText object bound to the above PdfContentByte object ColumnText ct = new ColumnText(cb); //Get the dimensions of the first page of our source document iTextSharp.text.Rectangle page1size = reader.GetPageSize(1); //Create a single column object spanning the entire page ct.SetSimpleColumn(0, 0, page1size.Width, page1size.Height); ct.AddElement(new Paragraph("Hello world!")); //Convert our HTML to iTextSharp elements List elements = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles); //Loop through each element (in this case there's actually just one PdfPTable) foreach (IElement el in elements) { //If the element is a PdfPTable if (el is PdfPTable) { //Cast it PdfPTable tt = (PdfPTable)el; //Change the widths, these are relative width by the way tt.SetWidths(new float[] { 75, 25 }); } //Add the element to the ColumnText ct.AddElement(el); } //IMPORTANT, this actually commits our object to the PDF ct.Go(); } } } this.Close(); } } }
 protected void LinkPdf_Click(object sender, EventArgs e) { Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=TestPage.pdf"); Response.Cache.SetCacheability(HttpCacheability.NoCache); StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); this.Page.RenderControl(hw); StringReader sr = new StringReader(sw.ToString()); Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f); HTMLWorker htmlparser = new HTMLWorker(pdfDoc); PdfWriter.GetInstance(pdfDoc, Response.OutputStream); pdfDoc.Open(); htmlparser.Parse(sr); pdfDoc.Close(); Response.Write(pdfDoc); Response.End(); }