Невозможно создать читаемый PDF с помощью метода iText 7 HtmlConverter.ConvertToDocument - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь использовать itext7 и itext7.pdfhtml для создания PDF-файла из некоторого HTML-кода на сервере, а затем возвращаю записанное значение MemoryStream как FileContentResult клиенту. Тем не менее, когда клиент получает PDF, все, что он получает, - это неоткрываемый PDF-файл, который, если расширение файла изменяется на .txt, может содержать только «% PDF-1.7%».

Поэкспериментировав с HtmlConverter.ConvertToPdf, я смог заставить работать простой контент из приведенного ниже примера (по крайней мере, его тело); тем не менее, я считаю, что вместо этого мне сейчас нужно HtmlConverter.ConvertToDocument, поскольку мне нужна возможность добавить нижний колонтитул и задать размер страницы и поля в результирующем PDF-файле с настройками, не содержащимися в переданном HTML-коде (другими словами, мне нужен iText Document объект для манипуляции).

Вот код, который я использую ...

public static byte[] GeneratePdfFromHtml(Action<Document> pdfModifier)
{
    //Gives the converter some very simple HTML for it to create something with!
    var html = "<html><head><title>Extremely Basic Title</title></head><body>Extremely Basic Content</body></html>";

    using (var workStream = new MemoryStream())
    using (var pdfWriter = new PdfWriter(workStream))
    using (var document = HtmlConverter.ConvertToDocument(html, pdfWriter))
    {
        //Passes the document to a delegated function to perform some content, margin or page size manipulation
        pdfModifier(document);

        //Returns the written-to MemoryStream containing the PDF.   
        return workStream.ToArray();
    }
}

Это была версия, с которой я работал, но в ней отсутствует объект, который мне нужно передать моему делегату.

public static byte[] GeneratePdfFromHtml(Action<Document> pdfModifier)
{
    //Gives the converter some very simple HTML for it to create something with!
    var html = "<html><head><title>Extremely Basic Title</title></head><body>Extremely Basic Content</body></html>";

    using (var workStream = new MemoryStream())
    using (var pdfWriter = new PdfWriter(workStream))
    {
        HtmlConverter.ConvertToPdf(html, pdfWriter);

        //No longer able to call this delegate as there is no Document object to use.
        //pdfModifier(document);

        //Returns the written-to MemoryStream containing the PDF.   
        return workStream.ToArray();
    }
}

1 Ответ

0 голосов
/ 08 мая 2018

В версии вы работали , которую вы использовали HtmlConverter.ConvertToPdf. Этот внутренний вызов также создает объект Document, но закрывает его перед возвратом.

Закрытие объекта Document приводит к тому, что все данные сгенерированного PDF, все еще находящиеся в памяти, сбрасываются в поток результатов, который затем завершается с помощью трейлера PDF.

Таким образом, ваша рабочая версия возвращает готовый, полный файл PDF.

В своем новом коде вы используете HtmlConverter.ConvertToDocument. Этот вызов возвращает использованный объект Document, но не закрывает его: вы все еще хотите использовать его для некоторых манипуляций.

Поскольку вы не закрываете объект Document перед вызовом return workStream.ToArray(), вы возвращаете неполный PDF, в вашем случае только раздел заголовка PDF.

Таким образом, вы должны закрыть этот Document объект перед извлечением байтов из вашего MemoryStream, например. явно так

using (var workStream = new MemoryStream())
using (var pdfWriter = new PdfWriter(workStream))
using (var document = HtmlConverter.ConvertToDocument(html, pdfWriter))
{
    //Passes the document to a delegated function to perform some content, margin or page size manipulation
    pdfModifier(document);

    document.Close();

    //Returns the written-to MemoryStream containing the PDF.   
    return workStream.ToArray();
}

или неявно так:

using (var workStream = new MemoryStream())
using (var pdfWriter = new PdfWriter(workStream))
{
    using (var document = HtmlConverter.ConvertToDocument(html, pdfWriter))
    {
        //Passes the document to a delegated function to perform some content, margin or page size manipulation
        pdfModifier(document);
    }

    //Returns the written-to MemoryStream containing the PDF.   
    return workStream.ToArray();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...