0

iText ライブラリ バージョン 4.1.6 で PDF ファイルを読み込んでいますが、通常はすべて正常に動作します。PDF 印刷ドライバー (MS Word の印刷機能付き) で作成された PDF を読むと、ASCII 文字が表示され、正しく変換できません。一部の PDF 記号は、トークン BT (Begin Text)、ET (End Text) などのように正しく変換されます。ただし、PDF 配列に格納されているテキスト オブジェクトに関しては (私の C# コードではなく、PDF ISO から! ) 単一の文字に奇妙な値があります。たとえば、'R' がありますが、バイト単位では値が '1' です。ASCII テーブルでは、R は '82' (10 進数) です。したがって、この文字に対して「SOH」のような値を取得します。他のライブラリはこれを何らかの方法で変換できます。この1バイトを文字「R」に変換する方法を教えてください。何時間も検索しましたが、今まで何も機能しませんでした。

PDFファイルを読む方法の最近のコードは次のとおりです(iText v。4.1.6)

public string ExtractPureText(string filename)
    {
        StringBuilder sb = new StringBuilder();

        // Create a reader for the given PDF file
        PdfReader reader = new PdfReader(filename);

        int totalLen = 68;
        float charUnit = ((float)totalLen) / (float)reader.NumberOfPages;

        for (int page = 1; page <= reader.NumberOfPages; page++)
        {
            sb.AppendLine(ExtractPureTextFromPDFBytes(reader.GetPageContent(page), page) + " ");
        }

        return sb.ToString();
    }

ExtractPureTextFromPDFBytes 関数は次のとおりです。

public string ExtractPureTextFromPDFBytes(byte[] input, int pageNumber)
    {
        if (input == null || input.Length == 0) return "";

        int readPosition = 0;
        Encoding enc = new UnicodeEncoding(true, false);

        try
        {
            string resultString = "";

            // Flag showing if we are we currently inside a text object
            bool inTextObject = false;

            // Flag showing if the next character is literal 
            // e.g. '\\' to get a '\' character or '\(' to get '('
            bool nextLiteral = false;

            // () Bracket nesting level. Text appears inside ()
            int bracketDepth = 0;

            // Keep previous chars to get extract numbers etc.:
            char[] previousCharacters = new char[_numberOfCharsToKeep];
            for (int j = 0; j < _numberOfCharsToKeep; j++) previousCharacters[j] = ' ';


            for (readPosition = 0; readPosition < input.Length; readPosition++)
            {
                char c = (char)input[readPosition];
                if (input[readPosition] == 213)
                    c = "'".ToCharArray()[0];


                if (inTextObject)
                {
                    byte[] b = new byte[2];
                    b[0] = 0;
                    b[1] = input[116];

                    byte[] d = new byte[1];
                    d[0] = input[116];
                    string bString = System.Text.Encoding.ASCII.GetString(b);

                    if (readPosition >= 114)
                    {
                        String t = new String((char)(input[116] & 0xff), 1);
                    }
                    // Position the text
                    if (bracketDepth == 0)
                    {
                        if (CheckToken(new string[] { "TD", "Td", "'", "T*", "\"", "TJ", "Tj", "Tf" }, previousCharacters))
                        {
                            resultString += System.Environment.NewLine;
                        }
                    }

                    // End of a text object, also go to a new line.
                    if (bracketDepth == 0 && CheckToken(new string[] { "ET" }, previousCharacters))
                    {
                        resultString += System.Environment.NewLine;
                        inTextObject = false;
                    }
                    else
                    {
                        // Start outputting text
                        if ((c == '(') && (bracketDepth == 0) && (!nextLiteral))
                        {
                            bracketDepth = 1;
                        }
                        else
                        {
                            // Stop outputting text
                            if ((c == ')') && (bracketDepth == 1) && (!nextLiteral))
                            {
                                bracketDepth = 0;
                            }
                            else
                            {
                                // Just a normal text character:
                                if (bracketDepth == 1)
                                {
                                    // Only print out next character no matter what. 
                                    // Do not interpret.
                                    if (c == '\\' && !nextLiteral)
                                    {
                                        //resultString += c.ToString();
                                        nextLiteral = true;
                                    }
                                    else
                                    {
                                        if (((c >= ' ') && (c <= '~')) ||
                                            ((c >= 128) && (c < 255)))
                                        {
                                            //resultString += c.ToString();
                                        }

                                        nextLiteral = false;
                                    }
                                }
                            }
                        }
                    }
                }

                resultString += c.ToString();

                // Store the recent characters for 
                // when we have to go back for a checking
                for (int j = 0; j < _numberOfCharsToKeep - 1; j++)
                {
                    previousCharacters[j] = previousCharacters[j + 1];
                }
                previousCharacters[_numberOfCharsToKeep - 1] = c;

                // Start of a text object
                if (!inTextObject && CheckToken(new string[] { "BT" }, previousCharacters))
                {
                    inTextObject = true;
                    resultString += System.Environment.NewLine;
                    resultString += pageNumber.ToString() + " PN" + System.Environment.NewLine;
                }
            }

            string output = string.Empty;

            // clean up text, remove empty lines and trim lines
            using (StringReader reader = new StringReader(resultString))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (line != string.Empty)
                    {
                        output += line + System.Environment.NewLine;
                    }
                }
            }

            return output;
        }
        catch
        {
            return "";
        }
    }

ライセンスが付与されているため、iText の上位バージョンを取得することは、私にとって絶対に不可能です。開発者ライセンスを持つライブラリがある場合に限りますが、iText ライセンスは、自分のソフトウェアがインストールされるすべてのマシンに対して支払う必要があります。残念ながら、これは私にとって選択肢ではありません。ご協力いただきありがとうございます

4

0 に答える 0