文本替换PDFSharp后,某些页面上生成的PDF中未显示的数字

时间:2014-04-24 14:57:33

标签: .net pdf reporting-services pdf-generation pdfsharp

我正在研究这个非常烦人的错误,其中数字8没有显示在我的PDF中。 1,2,3,4,5,6,7和0都很好,只有8个在一些页面上显示正方形(肖像画面)。

该应用程序的工作原理如下:

  • 在SSRS上生成PDF(某些风景,一些肖像)
  • 使用PDFSharp合并PDF
  • 使用PDFSharp更新页码

现在,在整个报告的第一部分(肖像页面)中,8没有显示。在报告的第二部分,8 IS显示。

我没有看到RDL(语言,字体,甚至盒子的大小)有任何差异。整个文档采用ANSI编码,因此编写新页码的代码对于整个文档是相同的。

8 not showing on first couple of pages

8 is showing on some of the other pages

我看到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。

通过SSRS生成PDFS的代码是相同的,当然除了报告名称。我在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

请注意,现在所有数字都显示为方框/方块..

1 个答案:

答案 0 :(得分:0)

感谢@mkl,我找到了解决方案。我们将在报告中添加一个隐藏的文本框,其中包含0123456789。原因是&#39;字体子集&#39;通过SSRS。

SSRS不会嵌入页面上未使用的字体字符以节省空间。因此,如果没有&#39; 8&#39;在页面上出现了&#39; 8&#39;替换为页面,是不可见的。因此,当我创建一个没有文字的页面时,我只得到了正方形/方框。

再次感谢@mkl。

请参阅:http://technet.microsoft.com/en-us/library/ms159713(SQL.100).aspx

  

如果可能,PDF呈现扩展程序会嵌入每个 子集   在PDF文件中显示报告所需的字体。字体   必须在报表服务器上安装报表中使用的。