ITextSharp Разбор HTML с изображениями в нем: он анализирует правильно, но не будет отображать изображения - PullRequest
9 голосов
/ 08 марта 2012

Я пытаюсь сгенерировать .pdf из html, используя библиотеку ITextSharp.Я могу создать PDF-файл с HTML-текстом, преобразованным в PDF-текст / параграфы

Моя проблема: В файле PDF не отображаются мои изображения (мои элементы img изHTML).Все мои img элементы html в моем html не отображаются в pdf?Возможно ли ITextSharp для анализа HTML и отображения изображений.Я очень на это надеюсь, иначе я напичкан: (

Я ссылаюсь на правильный каталог, где находятся изображения (используя IMG_BASURL), но они просто не показывают

Мой код:

// mainContents variable is a string containing my HTML
var document = new Document(PageSize.A4, 50, 50, 80, 100);
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.open();

Hashtable providers = new Hashtable();
providers.Add("img_baseurl","C:/users/xx/VisualStudio/Projects/myproject/");
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(mainContents), null, providers);
foreach (var htmlElement in parsedHtmlElements)
   document.Add(htmlElement as IElement);

document.Close();

Ответы [ 3 ]

11 голосов
/ 08 марта 2012

Каждый раз, когда я сталкивался с этим, проблема заключалась в том, что изображение было слишком большим для холста.Более конкретно, даже голый тег 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.

2 голосов
/ 16 июля 2015

Я столкнулся с той же проблемой и попробовал следующие предложенные решения: строка заменила тег, закодировала в base64 и вставила изображение в библиотеку классов .NET, но ни одна из них не сработала!Итак, я пришел к старомодному решению: добавление логотипа вручную с помощью doc.Add()
Вот ваш обновленный код:

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);
                        }
// here's the magic
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/HTMLTemplate/logo.png"));
                logo.SetAbsolutePosition(440, 800);
                document.Add(logo);
// end
                    }
                    doc.Close();
                }
            }
        }
0 голосов
/ 19 декабря 2012
string siteUrl = HttpContext.Current.Server.MapPath("/images/image/ticket/Ticket.jpg");
string HTML = "<table><tr><td><u>asdasdsadasdsa <img src='" + siteUrl + "' al='tt' /> </u></td></tr></table>";
...