5

我使用此代码使用 iTextSharp 阅读 pdf 内容。当内容是英语时它工作正常,但当内容是波斯语或阿拉伯语时它不起作用
结果是这样的:
是用于测试的示例非英语 PDF。

َٛنا ÙÙ"بÙ~طث یؿیٛÙ~ زؾا ÙÙ›ÙØÙ" Ù‚Ù›Ù…Ø ÛŒÙ"بٕس © Karl Seguin foppersian.codeplex。 com www.codebetter.com 1 1 ÙٔبÙ~طث َٛنا یؿیٛÙ~

همانرب لوصا یسیون  مرن دیلوت رتهب رازÙا

解决办法是什么 ?

  public string ReadPdfFile(string fileName)
        {
            StringBuilder text = new StringBuilder();

            if (File.Exists(fileName))
            {
                PdfReader pdfReader = new PdfReader(fileName);

                for (int page = 1; page <= pdfReader.NumberOfPages; page++)
                {
                    ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                    string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);

                    currentText = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.UTF8.GetBytes(currentText)));
                    text.Append(currentText);
                    pdfReader.Close();
                }
            }
            return text.ToString();
        }
4

1 回答 1

14

在 .Net 中,一旦你有了一个字符串,你就有了一个字符串,而且它始终是 Unicode 。实际的内存实现是 UTF-16,但这并不重要。永远永远不要将字符串分解为字节并尝试将其重新解释为不同的编码并将其作为字符串拍回去,因为这没有意义并且几乎总是会失败。

你的问题是这一行:

currentText = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.UTF8.GetBytes(currentText)));

我将把它分成几行来说明:

byte[] bytes = Encoding.UTF8.GetBytes("ی"); //bytes now holds 0xDB8C
byte[] converted = Encoding.Convert(Encoding.Default, Encoding.UTF8, bytes);//converted now holds 0xC39BC592
string final = Encoding.UTF8.GetString(converted);//final now holds ی

该代码将混淆 127 ASCII 障碍之上的任何内容。放下重新编码线,你应该会很好。

旁注,完全有可能创建一个字符串的任何东西都不正确,这实际上并不少见。但是你需要在它变成,级别之前解决这个问题。stringbyte

编辑

代码应该与上面的代码完全相同,只是应该删除一行。此外,无论您使用什么来显示文本,请确保它支持 Unicode。另外,正如@kuujinbo 所说,请确保您使用的是最新版本的 iTextSharp。我用 5.2.0.0 对此进行了测试。

    public string ReadPdfFile(string fileName) {
        StringBuilder text = new StringBuilder();

        if (File.Exists(fileName)) {
            PdfReader pdfReader = new PdfReader(fileName);

            for (int page = 1; page <= pdfReader.NumberOfPages; page++) {
                ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);

                text.Append(currentText);
            }
            pdfReader.Close();
        }
        return text.ToString();
    }

编辑 2

上面的代码修复了编码问题,但没有修复字符串本身的顺序。不幸的是,这个问题似乎在 PDF 级别本身。

因此,在这种从右到左的书写系统中显示文本需要单独定位每个字形(这既繁琐又昂贵),或者用显示字符串表示文本(参见 9.2,“字体的组织和使用”),其字符代码在相反的顺序。

PDF 2008 Spec - 14.8.2.3.3 - 逆序显示字符串

When re-ordering strings such as above, content is (if I understand the spec correctly) supposed to use a "marked content" section, BMC. However, the few sample PDFs that I've looked at and generated don't appear to actually do this. I absolutely could be wrong on this part because this is very much not my specialty so you'll have to poke around so more.

于 2012-04-17T13:07:30.187 回答