2012-02-26 41 views
3

我有一個過程,其中的html存儲在數據庫中的圖像鏈接。圖像也存儲在數據庫中。我創建了一個從數據庫讀取圖像的控制器動作。我正在生成的路徑類似/File/Image?path=Root/test.jpg。 這個圖像路徑嵌入在HTML中img標籤一樣<img alt="logo" src="/File/Image?path=Root/001.jpg" />使用itextsharp創建pdf與數據庫中的圖像

我嘗試使用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無法做到這一點,你可以提供給我任何其他可以完成此任務的第三方開源工具?

回答

4

如果圖像源不是包含協議的完全限定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); 

下面是一個完整的工作C#2010的WinForms應用定位iTextSharp的5.1.2.0演示瞭如何使用相對圖像並使用全局提供程序設置其基礎。儘管我通過一堆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(); 
     } 
    } 
} 
+0

謝謝,作品像一個魅力! – user1230089 2012-03-07 22:37:40

+0

@Chris,因爲你的代碼在「using」裏面,是否真的需要doc.Close()? – Alexandre 2014-03-17 21:09:09

+1

你是對的,我只是喜歡我的命令來平衡對方。如果我明確地使用open,那麼我想明確地使用close。個人喜好。 – 2014-03-17 21:28:12

相關問題