PdfBox codifica símbolo moneda euro

Creé un documento PDF con la biblioteca Apache PDFBox. Mi problema es codificar el símbolo de moneda del euro al dibujar una cadena en la página, porque la fuente base Helvetica no proporciona este carácter. ¿Cómo puedo convertir la salida “þÿ ¬” al símbolo “€” ?.

    Desafortunadamente, la encoding de cadenas de PDFBox dista mucho de ser perfecta (versión 1.8.x). Lamentablemente, utiliza las mismas rutinas cuando codifica cadenas en objetos PDF generics que cuando codifica cadenas en flujos de contenido, lo cual es fundamentalmente incorrecto. Por lo tanto, en lugar de usar PDPageContentStream.drawString (que usa esas codificaciones incorrectas), debe traducir usted mismo a la encoding correcta.

    Por ejemplo, en lugar de usar

      contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 2); contentStream.drawString("€"); contentStream.endText(); contentStream.close(); 

    lo que resulta en

    € codificación incorrecta

    podrías usar algo como

      contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 8); byte[] commands = "(x) Tj ".getBytes(); commands[1] = (byte) 128; contentStream.appendRawCommands(commands); contentStream.endText(); contentStream.close(); 

    Resultando en

    € codificación correcta

    Si se pregunta cómo llegué a utilizar 128 como código de bytes para el euro, eche un vistazo a la especificación PDF ISO 32000-1 , anexo D.2, conjunto de caracteres latinos y codificaciones que indica un valor octal 200 (decimal 128) para el Símbolo de € en WinAnsiEncoding.


    PD : Mientras tanto, un enfoque alternativo ha sido presentado por otras respuestas, que en el caso del símbolo € equivale a algo así como:

      contentStream.beginText(); contentStream.setTextMatrix(100, 0, 0, 100, 50, 100); contentStream.setFont(PDType1Font.HELVETICA, 8); contentStream.drawString(String.valueOf(Character.toChars(EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING).getCode("Euro")))); contentStream.endText(); contentStream.close(); 

    Esto de hecho también dibuja el símbolo ‘€’. Pero a pesar de que este enfoque se ve más limpio (no usa matrices de byte , no construye una operación de flujo de PDF real manualmente), está sucio a su manera:

    Para utilizar un método roto, en realidad rompe su argumento de cadena de la manera correcta para contrarrestar el error en el método.

    Por lo tanto, si la gente de PDFBox decidiera arreglar el método roto de PDFBox, este código de trabajo aparentemente limpio aquí comenzaría a fallar ya que luego alimentaría el método fijo con datos de entrada rotos.

    Es cierto que dudo que arreglen este error antes de 2.0.0 (y en 2.0.0 el método fijo tiene un nombre diferente), pero uno nunca sabe …

    Esto funcionó para mí:

     char symbol = '€'; Encoding e = EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING); String toPDF = String.valueOf(Character.toChars(e.getCode(e.getNameFromCharacter(symbol))));` 

    Una solución creada por muchos:

      String text = "Lorem ipsum dolor sit amet, consectetur adipisici € 1.234,56 " + "elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua."; contentStream.beginText(); contentStream.setFont(font, 12); contentStream.moveTextPositionByAmount(10, 500); char[] tc = text.toCharArray(); StringBuilder te = new StringBuilder(); Encoding e = EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING); for (int i = 0; i < tc.length; i++) { Character c = tc[i]; int code = 0; if(Character.isWhitespace(c)){ code = e.getCode("space"); }else{ code = e.getCode(e.getNameFromCharacter(c)); } te.appendCodePoint(code); } contentStream.drawString( te.toString() ); contentStream.endText(); contentStream.close(); 

    Para el espacio de caracteres es un código desconocido porque el nombre "spacehackarabic" no se describe en WinAnsiEncoding, no sé por qué se devuelve este nombre. De todos modos, tengo el verificador de espacios de caracteres, pero también es posible mapear este nombre con un espacio de código equivalente:

     e.addCharacterEncoding( 040, "spacehackarabic" ); 

    Gracias...

    Quizás es demasiado tarde, pero lo hice usando:

     String toPDF = String.valueOf(Character.toChars(e.getCode("Euro"))); 

    Asegúrese de poner mayúscula “E”, si lo hace “euro” arroja un error. Por favor, eche un vistazo a este enlace que me ayuda mucho http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt