【问题标题】:creating pdf with itextsharp with images from database使用 itextsharp 使用数据库中的图像创建 pdf
【发布时间】:2012-03-16 11:46:27
【问题描述】:

我有一个过程,其中 html 与图像链接一起存储在数据库中。图像也存储在数据库中。我创建了一个从数据库读取图像的控制器操作。我生成的路径类似于/File/Image?path=Root/test.jpg。 此图像路径嵌入在 img 标签中的 html 中,例如 <img alt="logo" src="/File/Image?path=Root/001.jpg" />

我正在尝试使用 itextsharp 从数据库中读取 html 并创建一个 pdf 文档

string _html = GenerateDocumentHelpers.CommissioningSheet(fleetId);
string _html = GenerateDocumentHelpers.CommissioningSheet(fleetId);
Document _document = new Document(PageSize.A4, 80, 50, 30, 65);
MemoryStream _memStream = new MemoryStream();
PdfWriter _writer = PdfWriter.GetInstance(_document, _memStream);
StringReader _reader = new StringReader(_html);            
HTMLWorker _worker = new HTMLWorker(_document);
_document.Open();            
_worker.Parse(_reader);
_document.Close();
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=Commissioning.pdf");
Response.ContentType = "application/pdf";
Response.Buffer = true;
Response.OutputStream.Write(_memStream.GetBuffer(), 0, _memStream.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
return new FileStreamResult(Response.OutputStream, "application/pdf");

此代码给了我一个非法字符错误。这来自图像标签,它不识别?和=字符,有没有办法可以用img标签渲染这个html,这样当我创建一个pdf时,它会从数据库中渲染html和图像并创建一个pdf,或者如果itextsharp不能这样做,你能提供给我吗有没有其他第三方开源工具可以完成这项任务?

【问题讨论】:

    标签: html database image pdf itext


    【解决方案1】:

    如果图像源不是包含协议的完全限定 URL,则 iTextSharp 假定它是基于文件的 URL。解决方案是将所有图像链接转换为http://YOUR_DOMAIN/File/Image?path=Root/001.jpg 形式的绝对链接。

    您还可以在解析器上设置一个与 HTML <BASE> 标记几乎相同的全局属性:

    //Create a provider collection to set various processing properties
    System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
    //Set the image base. This will be prepended to the SRC so watch your forward slashes
    providers.Add(HTMLWorker.IMG_BASEURL, "http://YOUR_DOMAIN");
    //Bind the providers to the worker
    worker.SetProviders(providers);
    worker.Parse(reader);
    

    以下是针对 iTextSharp 5.1.2.0 的完整工作 C# 2010 WinForms 应用程序,它展示了如何使用相对图像并使用全局提供程序设置其基础。一切都与您的代码几乎相同,尽管我通过一堆using 语句来确保正确清理。确保查看所有内容的前导斜杠和尾随斜杠,基本 URL 仅直接添加 SRC 属性,如果未正确完成,您可能会以双斜杠告终。我在这里强硬一个域,但你应该能够轻松地使用 System.Web.HttpContext.Current.Request 对象。

    using System;
    using System.IO;
    using System.Windows.Forms;
    using iTextSharp.text;
    using iTextSharp.text.html.simpleparser;
    using iTextSharp.text.pdf;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
                string html = @"<img src=""/images/home_mississippi.jpg"" />";
                string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf");
                using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
                    using (Document doc = new Document(PageSize.TABLOID)) {
                        using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
                            doc.Open();
    
                            using (StringReader reader = new StringReader(html)) {
                                using (HTMLWorker worker = new HTMLWorker(doc)) {
                                    //Create a provider collection to set various processing properties
                                    System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
                                    //Set the image base. This will be prepended to the SRC so watch your forward slashes
                                    providers.Add(HTMLWorker.IMG_BASEURL, "http://www.vendiadvertising.com");
                                    //Bind the providers to the worker
                                    worker.SetProviders(providers);
                                    worker.Parse(reader);
                                }
                            }
    
                            doc.Close();
                        }
                    }
                }
    
                this.Close();
            }
        }
    }
    

    【讨论】:

    • @Chris,由于您的代码在“使用”中,所以真的需要 doc.Close() 吗?
    • 你说得对,我只是喜欢我的命令来相互平衡。如果我明确使用 open,那么我喜欢明确使用 close。个人喜好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2012-07-03
    • 2018-12-27
    • 2015-01-01
    • 1970-01-01
    相关资源
    最近更新 更多