11
votes

Utilisation de la bibliothèque Java PDFBox pour écrire PDF russe

J'utilise une bibliothèque Java appelée PDFBox forte> Essayer d'écrire du texte à un fichier PDF. Cela fonctionne parfaitement pour le texte anglais, mais quand j'ai essayé d'écrire du texte russe à l'intérieur du fichier PDF, les lettres sont apparues si étranges. Il semble que le problème soit dans la police utilisée, mais je ne suis pas si sûr de cela, alors j'espère que si quelqu'un pouvait me guider à travers cela. Voici les lignes de code importantes:

COSDictionary cosDic = new COSDictionary();
cosDic.setString( COSName.getPDFName("Ercyrillic"), "0420 " ); // Russian letter.
font.setEncoding( new DictionaryEncoding( cosDic ) );


4 commentaires

N'est-il pas évident? Vous définissez la police sur le nouveau winansienceCoding (). Win + ANSI! = Capable de montrer le russe.


J'ai essayé tous les codages disponibles mais aucun n'a fonctionné, les codages disponibles sont sous-classées ici: 127.0.0.1:51381/help/nftopic/jar :file: : / Programmes / Java / ... Donc, le problème n'est pas dans la police, mais dans le codage?


12.0.0.1:51381? Localhost? cela ne fonctionnera que pour personne mais vous


Désolé ... Les codages disponibles sont sous-classées ici: Java2S.com/open-source/java-document/pdf/pdfbox-0.7.3/org/...


6 Réponses :


0
votes

Peut-être que la classe de codage russe doit être écrite, il devrait ressembler à la WinansienceCoding un, je suppose.
Maintenant, je n'ai aucune idée de quoi mettre là-bas!

ou, si ce n'est pas ce que vous faites déjà, vous devez peut-être coder votre fichier source dans UTF-8 et utiliser un codage par défaut.
J'ai vu des messages liés aux problèmes liés à l'extraction de texte russe des fichiers PDF existants (à l'aide de PDFBox bien sûr) mais je ne sais pas si la sortie est liée.
Vous pouvez également écrire dans la liste de diffusion PDFBOX.


2 commentaires

Eh bien, l'extraction de texte russe fonctionne correctement avec PDFBox, le problème consiste à écrire du texte russe dans un fichier PDF.


Pour écrire le codage rusien, il y a la classe de dictionnaire de dictionnaire que je pense peut me laisser définir mon propre codage ... mais cela me semble un labyrinthe: kickjava.com/src/org/pdfbox/encoding/...



0
votes

Test si un problème de codage doit être assez facile à faire (simplement passer à l'encodage UTF16).

Je suppose que vous avez essayé d'utiliser un éditeur ou quelque chose avec la police de Vremacci et confirmé qu'il affiche la façon dont vous vous attendez à ce que ce soit?

Vous voudrez peut-être essayer de faire la même chose dans IText Juste pour avoir une idée de savoir si le problème est lié à la bibliothèque PDFBox elle-même ... Si votre objectif principal est de Générez des fichiers PDF, IText pourrait être une meilleure solution de toute façon.

EDIT - Réponse longue aux commentaires:

OK - Désolé pour la question de l'encodage ... Votre noyau Le problème (que vous saviez probablement déjà) est que l'encodage des octets étant écrit dans le flux de contenu est différent du codage utilisé pour rechercher des glyphes. Maintenant, j'essaierai de réellement être utile:

J'ai examiné la classe d'encodage du dictionnaire dans PDFBOX, et il a l'air tout à fait inintuciant ... Le «dictionnaire» en question est un dictionnaire PDF. Donc, ce que vous aurez essentiellement besoin de faire est de créer un objet de dictionnaire PDF (je pense que PDFBox appelle cela un type de COSObject), puis ajoutez des entrées à elle.

Le codage pour une police est défini dans PDF. comme dictionnaire (voir page 266 de la spécification ci-dessus). Le dictionnaire contient un nom de codage de base, plus un tableau de différences facultatif. Techniquement, le réseau de différences ne doit pas être utilisé avec des polices de type véritable (bien que je l'ai vue utilisée dans certains cas - ne l'utilisez pas, cependant).

Vous spécifierez ensuite une entrée pour le CMAP pour le codage. Ce CMAP sera le codage de votre police.

Ma suggestion ici est de prendre un PDF existant qui fait ce que vous voulez, puis obtenez une vidage de la structure de dictionnaire pour la police afin que vous puissiez voir ce qu'il a l'air Comme.

Ceci n'est certainement pas pour la faiblesse du cœur. Je peux fournir une aide de l'aide - si vous avez besoin d'une vidange de dictionnaire, tirez-moi un lien hypertexte avec un échantillon de PDF et je vais l'exécuter à travers certains des algorithmes que j'utilise dans mon développement iText (je suis le responsable de l'extraction de texte ITEXT -ystem).

EDIT - 11/17/09

OK - Voici le DICTION DU DICTION DU FICHIER RUSSIBL.PDF (les sous-dictionnaires sont répertoriés en retrait et dans l'ordre est apparu dans le dictionnaire contenant): xxx

Il y a beaucoup de pièces mobiles ici. Vous voudrez peut-être assembler un document de test qui n'a que 3 ou 4 caractères dans la police en question ... Il y a beaucoup de polices de type-1 utilisées ici (en plus des polices TT), il est donc difficile de dire ce qui est impliqué dans votre problème particulier.

(êtes-vous sûr de ne pas vouloir au moins essayer cela avec ITEXT ?;-) Je ne dis pas que ça va marcher, juste que ça pourrait Virez-vous à une photo).

Pour référence, la vidange du dictionnaire ci-dessus a été obtenue à l'aide de la classe COM.Lowagie.text.pdf.parser.pdfcontReaderTool Class


12 commentaires

Il n'y a pas de classe dans PDFbox qui prend en charge UTF8 ou UTF16, mais je pense que oui, c'est un problème de codage. Je sais que ITEXT est une grande bibliothèque, mais j'ai déjà commencé mon travail avec PDFBox et c'est bon jusqu'à présent, donc je veux rester avec PDFbox.


Pouah. Si vous utilisez PDFBox pour analyser le contenu que vous avez créé, pouvez-vous récupérer le texte? Si tel est le cas, ce n'est probablement pas une limitation du codage, pré-séparez-vous ... peut-être que ce n'est qu'un problème avec la manière dont PDFbox Maps Maps Byte Uteples aux glyphes?


Que voulez-vous dire en la récupérant? Je peux écrire quelques autres langues étrangères comme le français, l'allemand, ... mais d'autres comme le russe semblent être un problème. C'est un problème de codage, je suis sûr. Et le dictionnaire de classe a été créé pour permettre d'étendre d'autres codages non pris en charge, mais je ne peux toujours pas comprendre comment l'utiliser.


Eh bien, si vous analysez le texte à l'aide de PDFBOX, obtenez-vous le texte que vous entrez, ou est-ce grignoté? En d'autres termes, écrivez Texte A au format PDF, puis lisez le texte A de PDF, puis voir si A? = A. Si c'est un problème de codage, il est peu probable que vous soyez symétrique, vous obtiendrez donc probablement un! = B Sortez. Si vous obtenez un = A = A, alors le problème n'est probablement pas codé et que vous avez affaire à un code de caractère-> problème de transformation de glyphe. Suggérez fortement que vous essayez cela à l'aide d'ITEXT afin que vous ayez au moins une ligne de base du contenu de contenu que vous devrait obtenir.


Eh bien, j'ai essayé cela, et il reçoit le même texte que j'entre aussi A = un retour vrai. D'autre part, je n'ai pas la différence entre le codage et la transformation de glyphe ... Je pensais qu'ils étaient la même chose. Quand j'ai parlé à l'administrateur de la bibliothèque, voici ce qu'il a dit: "Le problème est le mappage entre la chaîne à ajouter et le codage de la police. Afaik the WinansienceCoding, utilisé comme défaut pour les polices de type VRAI ne contient pas de lettres russes. . Donc, enfin, vous devez en quelque sorte trouver une autre façon pour la cartographie. Vous devriez être capable de définir votre propre cartographie à l'aide du dictionnaire. "


Merci beaucoup Kevin ... je suis vraiment impressionné. Eh bien, voici le code que j'ai essayé avant - je ne comprends pas vraiment ce que je fais ici :) Mais je pense que cela traduit ce que vous dites: Cosdictionnaire COSDIC = Nouveau Cosdictionnaire (); cosdiques.setstring (cosname.gepdfname ("ercyrillic"), "0420"); // lettre russe. Font.SetCoding (nouveau dictionnaire) (COSDIC)); Voulez-vous dire par la CMAP une carte générale comme la carte de la cosdiction? Voici un échantillon de PDF russe: 4shared.com/file/153847152/ac2943e0/Russian .html


Brad - Je vais jeter un coup d'oeil quand je reçois une minute libre. Vous voudrez peut-être poster le code ci-dessus dans la question initiale afin qu'elle formatera correctement. CMAP est un type de structure de données utilisée pour la communication d'informations de codage - ce n'est certainement pas un cosdictionnaire. La spécification PDF que je lie vers ci-dessus contient des informations sur les CMPAP (à nouveau, pas pour les faibles du cœur). PDFBox a un analyseur de fichiers CMAP décent intégré, donc si vous pouvez obtenir le CMAP pour la police, vous pouvez au moins analyser (je ne suis toujours pas certain de savoir comment cela fonctionnerait pour votre situation particulière.


Merci beaucoup Kevin, mais je ne sais pas que dois-je faire avec ce décharge :) ... J'ai créé une application de test pour écrire un PDF: 4Shared.com/file/154503635/62837B87/CreatebreekPDF.html ... Veuillez vérifier, double-cliquez sur le pot. J'ai aussi trouvé ceci: Pinxue.net/java/pdfbox_string_charseSt_analyze_en.html ... i Pensez que cela peut être utile, mais bien sûr que c'est tellement compliqué pour moi.


Ouais - Les entrées de police de dictionnaire ne sont pas simples. Une partie du problème que vous avez est que vous ayez beaucoup trop de polices dans le fichier unique. Lors de la creuser dans ce genre de choses, il est beaucoup plus facile de faire une police à la fois, avec seulement 4 ou 5 caractères de texte. Cela vous permet de vous concentrer sur le problème spécifique à portée de main. Cela dit, ce que vous ferez avec ce dictionnaire de dictionnaire est de créer un objet de dictionnaire COS (et des sous-dictionnaires, etc.), et utilisez-le pour votre codage. Ou vous pourriez essayer iText ;-)


Comme je l'ai dit ... Je sais que ITEXT est génial, mais j'ai déjà terminé mon programme il y a 3 mois, et c'est une mise à jour critique. Je ne peux donc pas changer la bibliothèque utilisée maintenant.


Assez juste. Engineering inverse Les dictionnaires de polices peuvent être un projet de 3 mois, bien que ... vous voudrez peut-être au moins essayer iText Just pour voir si cela fonctionne mieux. Je sais qu'il est difficile de changer de chevaux au milieu de la course, mais parfois, vous devez mordre cette balle (je devais faire ce changement moi-même dans un moment où j'ai découvert que PDFBox n'a pas pris en charge les flux Xref)


:) ... C'est une décision très difficile, mais je pense que je dois le faire. Je vais essayer et j'espère que je ne regretterai pas.



-1
votes

Essayez simplement celui-ci:

phrase gauche = nouvelle phrase ("Санкт-петербург", FontFactory.getfont ("Tahoma", "CP1251", True, 25));

Cela fonctionnera au moins avec le dernier (5.0.1) ITEXT


0 commentaires

5
votes

La longue histoire est celle-ci - afin de faire une sortie Unicode en PDF à partir d'une police TrueType, la sortie doit inclure une tonne d'informations détaillées et apparemment superflues. Ce qu'il va, c'est que cela - à l'intérieur d'une police TrueType Les glyphes sont stockés comme ID de glyphe. Ces identifiants de glyphes sont associés à un caractère unicode particulier (et IIRC, un glyphe unicode peut faire référence à plusieurs points de code - comme étant faisant référence à E et à un accent aigu - ma mémoire est brumeuse). PDF n'a pas vraiment de support unicode autre que de dire qu'il existe un mappage de valeurs UTF16BE dans une chaîne d'ID de glyphe dans une police TrueType, ainsi qu'un mappage des valeurs UTF16BE à UNICODE - même si c'est une identité.

  • Un dictionnaire de police de sous-type de type0 avec
    • Un tableau DescendantFontS avec une entrée décrite ci-dessous LI>
    • une entrée Tounicode qui mappe des valeurs UTF16BE sur UNICODE LI>
    • Un codage défini sur Identity-H LI> ul> li> ul>

      sortie de l'un de mes tests d'unité sur mes propres outils ressemble à ceci: p> xxx pré>

      endstream% note que le formatage est incorrect pour le flux p>

      • Un dictionnaire de police de sous-type cidfonttype2 avec
        • Un Cidssyteminfo Li>
        • Un FonDeDescriptor LI>
        • dw et w li>
        • un CidtogidMap qui correspond à l'ID de caractère à Glyph ID LI> ul> li> ul>

          Voici celui-ci du même test - il s'agit de l'objet dans le tableau DESCENDANTFONTS: P>

          4 0 obj
          << 
             /Subtype /CIDFontType2 
             /Type /Font 
             /BaseFont /DejaVuSansCondensed 
             /CIDSystemInfo 8 0 R 
             /FontDescriptor 9 0 R 
             /DW 1000 
             /W 10 0 R 
             /CIDToGIDMap 11 0 R 
          >>
          
          8 0 obj
          << 
             /Registry (Adobe)
             /Ordering (UCS)
             /Supplement 0 
          >>
          endobj
          


0 commentaires

0
votes

Essayez d'utiliser cette construction: xxx


1 commentaires

Au moment où j'ai posé cette question, PDFBOX ne soutenait que des langues latines en écriture, alors écrire le russe n'a pas été pris en charge. Maintenant, les gars qui ont créé PDFbox ont corrigé ce problème et soutient désormais les langues russes et autres, grâce à elles, et merci à vous de partager la solution :)



1
votes

La solution est très simple.

1) Vous devez trouver des polices compatibles avec les caractères que vous souhaitez afficher.
2) Télécharger localement le fichier .ttf des polices.
3) Chargez les polices de votre application

Par exemple, c'est ce que vous devez faire au cas où vous souhaitez utiliser des caractères grecs: xxx


0 commentaires