2017-12-06 22 views
0

私はiTextで作成したpdfを解析しようとしています。ヘルベチカ、サイズ:20 iText7でpdfを解析すると、一定の間隔(フリーセットフォント)で移動します

  • "Фамилия" - (ロシア語から "姓") - フォント: - - (ロシア語から "名前")フォント

    • "Имя":文書で私は2つの段落を持っていますFreeset(私はhereそれをダウンロードした)、サイズ:10

    私は私が代わりに「Фамилия」の「Имя」適切にエンコードし、「Ôàìèëèÿ」を取得し解析する終えます。 「Фамилия」のUnicode文字ですが、848文字(10ベース)が残されました。 (例えば、UTF-8の0x0424の代わりに "Ф"(0x0424)の代わりに "Ô"(0x00d4)が得られ、その差は848(または16進数で350)です)

    私はthisの例を使用します( "Имя"、 "Фамилия")

    私はとして英語以外の文字を格納することがわかっています。私は手で入力データからpdfを作成していますので、手動で別のUnicode記号として再入力することはできません(その場で行う方法を知っている場合は、あなたのアプローチを提供してください)。

    なぜこのチャーの動きアクターが起こり、それを避ける方法は歓迎されます。前もって感謝します。

    Hereは私が扱ったファイルです。

    編集

    私はプロAcrobatで開いたファイルを試してみましたが、すべてがそこに罰金です。 Acrobatはまた、私がpdfに書いた3つのフォントがすべて文書に残っていることを示しています。ここで

    は私が処理していますPDFファイルを作成するために使用するコードです:

    private static void create() throws IOException { 
        PdfDocument pdf = new PdfDocument(new PdfReader(srcPdf), new PdfWriter(targetPdf)); 
        PdfCanvas pdfCanvas = new PdfCanvas(pdf.getFirstPage()); 
        PdfFont freeset = getPdfFont(freesetPath); 
        PdfFont helvetica = getPdfFont(helveticaPath); 
        PdfFont circe = getPdfFont(circePath); 
        pdfCanvas.beginText() 
          .setFontAndSize(helvetica, 15) 
          .setColor(Color.RED, true) 
          .moveText(50, 300) 
          .showText("Имя") 
          .setFontAndSize(freeset, 10) 
          .setColor(Color.GREEN, true) 
          .moveText(0, -30) 
          .showText("Фамилия") 
          .setFontAndSize(circe, 20) 
          .setColor(Color.BLUE, true) 
          .moveText(0, -30) 
          .showText("Должность") 
          .endText(); 
    
        pdf.close(); 
    } 
    
    private static PdfFont getPdfFont(String path) throws IOException { 
        InputStream fontInputStream = new FileInputStream(path); 
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        byte[] buffer = new byte[2048]; 
        int a; 
        while((a = fontInputStream.read(buffer, 0, buffer.length)) != -1) { 
         baos.write(buffer, 0, a); 
        } 
        baos.flush(); 
        return PdfFontFactory.createFont(baos.toByteArray(), 
          PdfEncodings.IDENTITY_H, true); 
    } 
    
  • +1

    問題のPDFを共有してください。 – mkl

    +0

    これらの文字列を読むときは 'UTF-8'を使用していますか? – Eugene

    +0

    @mklが質問へのリンクを追加しました。他のテキストもありますが、問題は薄い緑色のテキスト "Фамилия"です。 –

    答えて

    1

    iTextの7は、問題のフォントを埋め込むことで、問題を持っているように見えます。私はフォントやiTextのバグかどうかはわかりません。


    "FreeSet" フォントは確かに間違ってのToUnicodeマップ

    00d4に "Фамилия" に使用するグリフをマップ
    ... 
    6 beginbfrange 
    <009e> <009e> <00d4> <00aa> <00aa> <00e0> <00b2> <00b2> <00e8> <00b5> <00b5> <00eb> <00b6> <00b6> <00ec> <00c9> <00c9> <00ff> endbfrange 
    ... 
    

    、00E0、00E8、とOPのサンプル文書に埋め込まれています00eb、00ec、および00ff。

    これは、iTextとAdobe Readerの両方が予期しないテキストを抽出する理由を説明しています。

    問題は次のように再現することができます。

    PdfFont arial = PdfFontFactory.createFont(BYTES_OF_ARIAL_FONT, PdfEncodings.IDENTITY_H, true); 
    PdfFont freeSet = PdfFontFactory.createFont(BYTES_OF_FREESET_FONT, PdfEncodings.IDENTITY_H, true); 
    
    try ( OutputStream result = new FileOutputStream("cyrillicTextFreeSet.pdf"); 
         PdfWriter writer = new PdfWriter(result); 
         PdfDocument pdfDocument = new PdfDocument(writer); 
         Document doc = new Document(pdfDocument) ) { 
        doc.add(new Paragraph("Фамилия").setFont(arial)); 
        doc.add(new Paragraph("Фамилия").setFont(freeSet)); 
    } 
    

    CreateCyrillicTextテストtestCreateTextWithFreeSet

    結果はOKになります:/

    screenshot

    を抽出&貼り付けをコピーします、でも:

    組み込みArialサブセットには適切なToUnicodeマップがあり、Arialのテキストは "Фамилия"として抽出されます。

    埋め込みFreeSetサブセットに不正なToUnicodeマップがあり、FreeSetのテキストが "Ôàìèëèÿ"として抽出されます。

    (現在のiTextの7.1.1-SNAPSHOTでテスト済み)

    どうやらiTextの7は、必要なサブセットを選択し、コンテンツから正しいグリフを参照するために十分FreeSetフォントプログラムを理解しないが、それは問題を抱えています適切なものを構築するToUnicode地図。しかし、これは一般的な問題ではありませんが、Arialとの並行テストが示されています。

    +0

    ありがとうございます。私は別の問題を発見した、それは接続することができます。 'page.getFirstContentStream()'でPdfStreamを見て、 "Имя"(私は '<01a101c501d8> Tj'を持っています)のシンボルを見つけたとき、私はそれらもシフトされていることに気付きました(しかし631 10ベース)。ここでのフリーセットシフトについては、Circe Light - 705については902です。この論理(シフトを予測する方法)を知っているかもしれませんか?もしそうなら、私はPdfStreamsで私の問題を解決することができました。 –

    関連する問題