每我遇到過這個問題的時候,圖片對於畫布來說太大了,更具體地說,即使是一個全裸的IMG
標籤也會被包裝在一個Chunk
中,並且會被包裝在Paragraph
中,我認爲圖片是溢出段落,但我不是100%肯定。
這兩個簡單的修復方法是放大畫布或指定HTML IMG
標記上的圖像尺寸。第三種更復雜的路線是使用額外的供應商IMG_PROVIDER
。要做到這一點,你需要實現IImageProvider
接口。下面是一個
public class ImageThing : IImageProvider {
//Store a reference to the main document so that we can access the page size and margins
private Document MainDoc;
//Constructor
public ImageThing(Document doc) {
this.MainDoc = doc;
}
Image IImageProvider.GetImage(string src, IDictionary<string, string> attrs, ChainedProperties chain, IDocListener doc) {
//Prepend the src tag with our path. NOTE, when using HTMLWorker.IMG_PROVIDER, HTMLWorker.IMG_BASEURL gets ignored unless you choose to implement it on your own
src = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\" + src;
//Get the image. NOTE, this will attempt to download/copy the image, you'd really want to sanity check here
Image img = Image.GetInstance(src);
//Make sure we got something
if (img == null) return null;
//Determine the usable area of the canvas. NOTE, this doesn't take into account the current "cursor" position so this might create a new blank page just for the image
float usableW = this.MainDoc.PageSize.Width - (this.MainDoc.LeftMargin + this.MainDoc.RightMargin);
float usableH = this.MainDoc.PageSize.Height - (this.MainDoc.TopMargin + this.MainDoc.BottomMargin);
//If the downloaded image is bigger than either width and/or height then shrink it
if (img.Width > usableW || img.Height > usableH) {
img.ScaleToFit(usableW, usableH);
}
//return our image
return img;
}
}
一個非常簡單的版本要使用此供應商只需將其添加到供應商收集像你HTMLWorker.IMG_BASEURL
做:
providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc));
應當注意的是,如果你使用HTMLWorker.IMG_PROVIDER
你負責搞清楚形象的一切。上面的代碼假定所有圖像路徑都需要用一個常量字符串前綴,您可能需要更新它並在開始時檢查HTTP
。另外,因爲我們說我們想完全處理圖像處理流水線,所以不再需要供應商HTMLWorker.IMG_BASEURL
。
的主要代碼迴路現在看起來是這樣的:
string html = @"<img src=""Untitled-1.png"" />";
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.A4, 50, 50, 80, 100)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
using (StringReader sr = new StringReader(html)) {
System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc));
var parsedHtmlElements = HTMLWorker.ParseToList(sr, null, providers);
foreach (var htmlElement in parsedHtmlElements) {
doc.Add(htmlElement as IElement);
}
}
doc.Close();
}
}
}
最後一兩件事,一定要指定張貼在這裏,當你靶向其中iTextSharp的版本。上面的代碼針對iTextSharp 5.1.2.0,但我認爲你可能會使用4.X系列。
我試圖創建和使用基於這種代碼實現IImageProvider一類,但它不工作,我相信它與這條線有關: providers.Add(HTMLWorker。IMG_PROVIDER,新ImageThing(doc)); 我在C#中編碼,當我添加到我的散列表時,我無法使用HTMLWorker.IMG_PROVIDER枚舉。如果這個值只是一個字符串,這有什麼關係嗎?也許我需要從循環內部做更多的事情來實際執行ImageProvider類中的GetImage代碼。我使用的是itextsharp 4.1.6,以防萬一。 – Neitherman 2014-02-06 14:36:33
@Neitherman,請發表一個新的問題與你的嘗試和什麼不工作,引用這篇文章,如果它是有道理的。 – 2014-02-07 14:35:31
發佈新問題: http://stackoverflow.com/questions/21684040/imageprovider-not-working-in-html-to-pdf-conversion – Neitherman 2014-02-10 17:32:30