Числа не отображаются в сгенерированном PDF-файле на некоторых страницах после замены текста PDFSharp

Я работаю над этой чрезвычайно раздражающей ошибкой, когда число 8 не отображается в моем PDF-файле. 1,2,3,4,5,6,7 и 0 в порядке, только 8 показывает квадрат на НЕКОТОРЫХ страницах (портретных).

Приложение работает следующим образом:

  • Создайте PDF на SSRS (некоторый пейзаж, некоторый портрет)
  • Слияние PDF с помощью PDFSharp
  • Обновление номеров страниц с помощью PDFSharp

Теперь в первой части общего отчета (портретные страницы) цифра 8 не отображается. Во второй части отчета показаны 8 IS.

Я не вижу никаких отличий в RDL (язык, шрифты, даже размер коробки). Весь документ находится в кодировке ANSI, поэтому код для записи новых номеров страниц одинаков для всего документа.

8 не отображается на первых нескольких страницах

8 отображается на некоторых других страницах

Я видел, что у Aspose была подобная проблема (http://www.aspose.com/community/forums/thread/528718/number-8-missing-in-pdf-file-with-some-viewers.aspx), но я не использую Aspose.

Я проверил добавление (символ) 0x38, и он не отображается. 0x37 и 0x39 есть. Кодирование строк выполняется для обоих случаев, таких как Encoding.GetEncoding(1252).GetBytes() или Encoding.Default.

Код для создания PDFS через SSRS идентичен, за исключением, конечно, имени отчета. Я не смог найти никакой информации о кодировке в самом RDL.

Номера страниц заменяются с помощью PDFSharp Stream.Value = 'newvalue'.

Все идеи ОЧЕНЬ приветствуются.

ОБНОВЛЕНИЕ: я провел замену номера через Aspose, и цифра 8 появилась, как и ожидалось, на всех страницах. Используя простой pdf.Pages.Accept(textFragmentAbsorber);.

Обновление II

Итак, немного поигравшись, я почти уверен, что это связано с тем, как я заменяю текст в документе, и с кодировкой замененной строки.

Извлечение происходит следующим образом:

    public byte[] UpdatePageNumbers(byte[] file, PageNumberingConfigurationBase config)
    {
        var doc = PdfReader.Open(new MemoryStream(file), PdfDocumentOpenMode.Modify);
        for (int i = 0; i < doc.PageCount; i++)
        {
            var pageNr = i + 1;
            var page = doc.Pages[i];

            for (int j = 0; j < page.Contents.Elements.Count; j++)
            {
                var element = page.Contents.Elements.GetDictionary(j);
                var content = element.AsString();

                if (content.Contains(config.SearchTemplate))
                {
                    var newContent = content.Replace(
                        config.SearchTemplate,
                        config.GetReplacementTextForPage(pageNr, doc.PageCount));

                    element.Stream.Value = newContent.AsByteArray();
                }
            }
        }

        return doc.AsByteArray();
    }

С вспомогательным классом:

public static class ElementExtensions
{
    public static string AsString(this PdfDictionary dict)
    {
        return GetString(dict.Stream.Value);
    }

    public static byte[] AsByteArray(this string stream)
    {
        return GetBytes(stream);
    }

    static byte[] GetBytes(string str)
    {
        return Encoding.GetEncoding(1252).GetBytes(str);
    }

    static string GetString(byte[] bytes)
    {
        return Encoding.GetEncoding(1252).GetString(bytes);
    }
}

Кодировка документа внутри PDF:

/Encoding /WinAnsiEncoding

Вот как документы объединяются:

    public byte[] MergePdf(params byte[][] pdfs)
    {
        var outputDocument = new PdfDocument();

        for (int i = 0; i < pdfs.Count(); i++)
        {
            var document = PdfReader.Open(new MemoryStream(pdfs[i]), PdfDocumentOpenMode.Import);

            // Create the output document
            foreach (PdfPage pdfPage in document.Pages)
            {
                outputDocument.Pages.Add(pdfPage);
            }
        }

        return outputDocument.AsByteArray();
    }

Примеры файлов

Итак, вот примеры файлов:

Это один отчет, созданный 3 раза, затем объединенный, затем номера страниц обновлены. https://www.dropbox.com/s/yxzqw0y2tvu3v9a/before_update.pdf https://www.dropbox.com/s/ui26l0qsunhcune/after_update.pdf

Обратите внимание, что теперь ВСЕ числа отображаются в виде прямоугольников/квадратов.


person Jochen van Wylick    schedule 24.04.2014    source источник
comment
Какой просмотрщик использовали? Только один или несколько (включая канонически правильный бесплатный Acrobat Reader)? Можете ли вы создать одностраничный PDF-файл, демонстрирующий проблему, и опубликовать его в общедоступном месте?   -  person Jongware    schedule 24.04.2014
comment
И Фокс, и Адоб. Хм... это немного сложно, так как я делаю проект для крупного банка, и я боюсь, что они не хотят, чтобы я размещал их материалы в Интернете. Я посмотрю, что я могу сделать, хотя.   -  person Jochen van Wylick    schedule 24.04.2014
comment
Я бы поддержал запрос @Jongware на образец документа. Кроме того, вы, кажется, заменяете идентификаторы символов номеров страниц, изначально представленные в документе, своими новыми. Возможно ли, что шрифт, используемый для них, только частично встроен и просто не содержит глифа для 8? Вероятно, только в случае исходных документов с альбомной ориентацией глиф для 8 не встроен. Если вам действительно приходится иметь дело с частично встроенными шрифтами, я бы предложил полностью удалить исходные номера страниц и добавить новые, используя шрифт, который вы явно добавляете в объединенный документ.   -  person mkl    schedule 25.04.2014
comment
Я буду работать над этим. Могу сказать, что шрифт простой Verdana 7pt, ничего особенного. Это тот же шрифт, который используется на других страницах, которые работают. Все они заменяются в том же цикле, который проходит через элементы страницы PDFSharp.   -  person Jochen van Wylick    schedule 25.04.2014
comment
Боюсь, что без образца документа мы можем только догадываться. Кроме того, могут помочь основные разделы кода.   -  person mkl    schedule 25.04.2014
comment
Извлечение выглядит следующим образом. Таким образом, вы действительно просто редактируете строку содержимого, не проверяя, содержатся ли глифы для редактируемой строки в текущем шрифте, когда строка рисуется. Кодировка документа внутри PDF: /Encoding /WinAnsiEncoding - это не означает, что в шрифте присутствуют глифы для всех символов WinAnsi.   -  person mkl    schedule 25.04.2014
comment
@mkl, спасибо за вашу постоянную поддержку. Вы правы, дело в том, что я не понимаю, почему это отображается на одной странице, а не на другой, и мы говорим о Вердане и цифре 8. Я сейчас работаю над пустым RDL, чтобы воспроизвести это раздражает вопрос, то я могу предоставить вам образец.   -  person Jochen van Wylick    schedule 25.04.2014
comment
дело в том, что я не понимаю, почему... - скорее всего, разные подмножества рассматриваемого шрифта включены в ресурсы шрифтов, на которые ссылаются эти разные страницы.   -  person mkl    schedule 25.04.2014
comment
Еще раз спасибо - я добавил образцы файлов.   -  person Jochen van Wylick    schedule 25.04.2014
comment
@mkl - Так может ли быть так, что у меня возникла проблема из-за того, что на этой конкретной странице не использовалось 8 и, следовательно, оно было недоступно? Если да, можем ли мы решить эту надпись «0123456789» где-то невидимым на странице?   -  person Jochen van Wylick    schedule 25.04.2014
comment
Можем ли мы решить эту надпись '0123456789' где-то невидимым на странице? Да, это звучит правдоподобно, очевидно, с использованием того же шрифта, что и в нижнем колонтитуле страницы.   -  person mkl    schedule 25.04.2014


Ответы (1)


Благодаря @mkl я нашел решение. Мы собираемся добавить в отчет скрытое текстовое поле с 0123456789 внутри. Причина в «поднаборе шрифта» SSRS.

SSRS не будет встраивать символы шрифта, которые не используются на странице, для экономии места. Следовательно, если на странице не было «8», «8», заменившая страницу, не была видна. Поэтому, когда я создал страницу без текста, я получил только квадраты/прямоугольники.

Еще раз спасибо @mkl.

См.: http://technet.microsoft.com/en-us/library/ms159713%28SQL.100%29.aspx

Когда это возможно, модуль обработки PDF встраивает подмножество каждого шрифта, необходимого для отображения отчета в файле PDF. Шрифты, используемые в отчете, должны быть установлены на сервере отчетов.

person Jochen van Wylick    schedule 25.04.2014