Я работаю над этой чрезвычайно раздражающей ошибкой, когда число 8 не отображается в моем PDF-файле. 1,2,3,4,5,6,7 и 0 в порядке, только 8 показывает квадрат на НЕКОТОРЫХ страницах (портретных).
Приложение работает следующим образом:
- Создайте PDF на SSRS (некоторый пейзаж, некоторый портрет)
- Слияние PDF с помощью PDFSharp
- Обновление номеров страниц с помощью PDFSharp
Теперь в первой части общего отчета (портретные страницы) цифра 8 не отображается. Во второй части отчета показаны 8 IS.
Я не вижу никаких отличий в RDL (язык, шрифты, даже размер коробки). Весь документ находится в кодировке ANSI, поэтому код для записи новых номеров страниц одинаков для всего документа.
Я видел, что у 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 а>
Обратите внимание, что теперь ВСЕ числа отображаются в виде прямоугольников/квадратов.
/Encoding /WinAnsiEncoding
- это не означает, что в шрифте присутствуют глифы для всех символов WinAnsi. - person mkl   schedule 25.04.2014