Codificación FPDF utf-8 (CÓMO)

80

¿Alguien sabe cómo configurar la codificación en el paquete FPDF en utf-8? ¿O al menos ISO-8859-7 (griego) que admite caracteres griegos?

Básicamente, quiero crear un archivo pdf que contenga caracteres griegos.

Cualquier sugerencia ayudaría. Jorge

yorgos
fuente
Si desea utilizar más idiomas, necesita UTF8, por lo que puede utilizar tFPDF. Eche un vistazo al paquete del compositor .
robsch

Respuestas:

116

No utilice codificación UTF-8. Las fuentes FPDF estándar utilizan ISO-8859-1 o Windows-1252. Es posible realizar una conversión a ISO-8859-1 con utf8_decode(): $str = utf8_decode($str); Pero algunos caracteres como el euro no se traducirán correctamente. Si la extensión iconv está disponible, la forma correcta de hacerlo es la siguiente: $str = iconv('UTF-8', 'windows-1252', $str);

Michal
fuente
22
No creo que esto ayude. Su respuesta explica cómo generar un PDF con codificación ISO-8859-1 o windows-1252, pero estas codificaciones no funcionarán para idiomas no latinos. Sin mencionar la salida de textos en varios idiomas (multi-script).
Томица Кораћ
3
@Rafiq: no use el FPDF "antiguo" sino el tFPDF de la versión UTF8 más reciente como se publicó en mi Respuesta.
Tarsis
1
Nota: Cuando utilice ISO-8859-1, el carácter € no funcionará (no hay un signo de euro en el juego de caracteres, utilice ISO-8859-15 en su lugar).
BurninLeo
1
@BurninLeo: ISO-8859-15 no es mucho mejor, todas esas codificaciones tienen el mismo límite de caracteres, entonces -15 tiene € pero por lo tanto falta ´ o ½. La única solución real es usar UTF-8 en lugar de evitarlo, como se muestra en mi respuesta.
Tarsis
3
tFPDF admite Unicode, pero no se ha actualizado en 3 años, mientras que FPDF se ha actualizado más recientemente, lo que hace que tFPDF esté desactualizado. Tenga esto en cuenta cuando utilice tFPDF.
Agilis
38

También hay una versión UTF-8 oficial de FPDF llamada tFPDF http://www.fpdf.org/en/script/script92.php

Puede cambiar fácilmente desde el FPDF original, solo asegúrese de usar también una fuente Unicode como se muestra en el ejemplo en el enlace anterior o mi código:

<?php

//this is a UTF-8 file, we won't need any encode/decode/iconv workarounds

//define the path to the .ttf files you want to use
define('FPDF_FONTPATH',"../fonts/");
require('tfpdf.php');

$pdf = new tFPDF();
$pdf->AddPage();

// Add Unicode fonts (.ttf files)
$fontName = 'Helvetica';
$pdf->AddFont($fontName,'','HelveticaNeue LightCond.ttf',true);
$pdf->AddFont($fontName,'B','HelveticaNeue MediumCond.ttf',true);

//now use the Unicode font in bold
$pdf->SetFont($fontName,'B',12);

//anything else is identical to the old FPDF, just use Write(),Cell(),MultiCell()... 
//without any encoding trouble
$pdf->Cell(100,20, "Some UTF-8 String");

//...
?>

Creo que es mucho más elegante usar esto en lugar de usar spam utf8_decode () en todas partes y la capacidad de usar archivos .ttf directamente en AddFont () también es una ventaja.

Cualquier otra respuesta aquí es solo una forma de evitar o solucionar el problema, y ​​evitar UTF-8 no es una opción real para un proyecto actualizado.

También existen alternativas como mPDF o TCPDF (y otras) que se basan en FPDF pero ofrecen funciones avanzadas, tienen soporte UTF-8 y pueden interpretar código HTML (limitado por supuesto ya que no hay forma directa de convertir HTML a PDF). La mayor parte del código FPDF se puede usar directamente en esas bibliotecas, por lo que es bastante fácil migrar el código.

https://github.com/mpdf/mpdf http://www.tcpdf.org/

Tarsis
fuente
1
Ninguna de las soluciones de decodificación y iconv funciona para los personajes más excepcionales (♠ ♥ ☺äκόσμος). Pero si simplemente reemplaza su archivo fpdf.php con el archivo tpdf.php, todo comienza a funcionar y sus archivos se vuelven más pequeños como una ventaja adicional. Gran arreglo.
Sebastian
1
¿FPDF y tFPDF son ramas separadas? ¿Alguien sabe la razón por la que tFPDF está tan bien escondido en la página FPDF? ¿Hay algún inconveniente que conviene saber antes de cambiar?
BurninLeo
1
No estoy seguro de por qué no la convirtieron en la versión FPDF predeterminada, pero está vinculada directamente en la página principal fpdf.org y, como se menciona allí, las características de tFPDF se desarrollaron originalmente para mPDF. He usado tFPDF para muchos archivos PDF en un entorno productivo y creo que, además del UTF-8 y los cambios de fuente, es 100% igual. Nunca tuve problemas.
Tarsis
1
tFPDF es un script o una extensión de FPDF. Se considera desactualizado (actualizado hace 3 años) porque FPDF se ha actualizado más recientemente. El autor de tFPDF no lo mantiene actualizado y el GitHub asociado con tFPDF no se ha tocado. Ver: github.com/rev42/tfpdf
Agilis
Mientras no necesite más funciones, no veo un problema en eso, por cierto, la última actualización (menor) fue hace solo 4 meses, aún mejor que no admitir UTF-8. De cualquier manera, preferiría TCPDF o mPDF, que se basan en FPDF pero ofrecen funciones avanzadas y también admiten código HTML.
Tarsis
28

hay una solución realmente sencilla para este problema.

En el archivo fpdf.php vaya a la línea que dice:

if($txt!=='')
{

Es la línea 648 en mi versión de fpdf. Inserte la siguiente línea de código:

$txt = iconv('utf-8', 'cp1252', $txt);

(encima de la línea de código)

if($align=='R')

Esto funciona para todos los caracteres especiales alemanes y también debería funcionar para los caracteres especiales griegos. De lo contrario, simplemente reemplace cp1252 con el alfabeto respectivo que necesite. Puede ver todos los caracteres admitidos aquí: http://en.wikipedia.org/wiki/Windows-1252

Vi la solución aquí: http://fudforum.org/forum/index.php?t=msg&goto=167345 Utilice mi código de ejemplo anterior, ya que el autor original olvidó insertar un guión entre utf y 8.

Espero que lo anterior haya sido útil.

Daan

Daan
fuente
Perfecto, esto aún funciona o es necesario después de actualizar FPDF a una versión que admita PHP7 para mostrar caracteres especiales correctamente.
Aren
1
Este comando funciona para mí, $ txt = iconv ('utf-8', 'cp1252', $ txt); Thks
Patrick Arguello
Simplemente increíble solución simple. Triste, está escondido en un lugar oscuro en stackoverflow :)
Pieter-Jan Casteels
Esto cambió algo con mi espaciado: algunas líneas se rompen antes. Pero al menos parece funcionar: antes, la letra turca no me funcionaba en absoluto, ahora al menos veo algo.
Cold_Class
9

Primero debes generar una fuente. Debe utilizar la MakeFontutilidad incluida en el paquete FPDF. Usé en Linux este script un poco extendido de la demostración:

<?php
// Generation of font definition file for tutorial 7
require('../makefont/makefont.php');

$dir = opendir('/usr/share/fonts/truetype/ttf-dejavu/');
while (($relativeName = readdir($dir)) !== false) {
    if ($relativeName == '..' || $relativeName == '.')
        continue;
    MakeFont("/usr/share/fonts/truetype/ttf-dejavu/$relativeName",'ISO-8859-2');
}
?>

Luego copié los archivos generados al fontdirectorio de mi web y usé esto:

$pdf->Cell(80,70, iconv('UTF-8', 'ISO-8859-2', 'Buňka jedna'),1);

(Estaba trabajando en una mesa.) Eso funcionó para mi idioma ( Buňka jedna es checo para Cell uno ). El idioma checo pertenece a los idiomas de Europa Central, también ISO-8859-2. Lamentablemente, el usuario de FPDF se ve obligado a perder las ventajas de la codificación UTF-8. No puede obtener esto en su PDF:

Městečko Fruens Bøge

La letra danesa se øconvierte řen ISO-8859-2.

Sugerencia de solución: debe obtener una fuente griega, generar la fuente con la codificación adecuada (ISO-8859-7) y utilizarla iconvcon la misma codificación de destino con la que se generó la fuente.

Theodor Keinstein
fuente
4

Ninguna de las soluciones anteriores funcionará.

Prueba esto:

function filter_html($value){
    $value = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
    return $value;
}
Ankit Shukla
fuente
4

Puede hacer una clase para extender FPDF y agregar esto:

class utfFPDF extends FPDF {

function Cell($w, $h=0, $txt="", $border=0, $ln=0, $align='', $fill=false, $link='')
{
    if (!empty($txt)){
        if (mb_detect_encoding($txt, 'UTF-8', false)){
            $txt = iconv('UTF-8', 'ISO-8859-5', $txt);

        }
    }
    parent::Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);

} 

}

Alejandro Aranda
fuente
4

Quería responder esto para cualquiera que no se haya cambiado a TFPDF por cualquier motivo (integración de marco, etc.)

Vaya a: http://www.fpdf.org/makefont/index.php

Utilizar una .ttf fuente compatible para el idioma que desea utilizar. Asegúrese de elegir el número de codificación correcto para su idioma. Descargue los archivos y péguelos en su directorio de fuentes FPDF actual.

Use esto para activar la nueva fuente: $pdf->AddFont($font_name,'','Your_Font_Here.php');

Entonces puedes usarlo $pdf->SetFontnormalmente.

En la fuente en sí, use iconv para convertir a UTF-8. Entonces, si por ejemplo estás usando hebreo, lo harías iconv('UTF-8', 'windows-1255', $first_name).

Sustituya el número de codificación de Windows por su codificación de idioma.

De derecha a izquierda, una solución rápida es hacer algo como strrev(iconv('UTF-8', 'windows-1255', $first_name)).

rozick
fuente
4

simplemente edite la celda de función en el archivo fpdf.php, busque la línea que se ve así

function cell ($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = false, $link = '')
{ 

después de encontrar la línea

escribir después del {,

$txt = utf8_decode($txt);

guarde el archivo y listo, los acentos y la codificación utf8 estarán funcionando :)

R.Costa
fuente
3

¿Cómo creo PDF en FPDF que sean compatibles con chino, japonés, ruso, etc.?

(instantáneas del código en uso a continuación)

Me gustaría proporcionar: un resumen del problema, la solución, un proyecto de github con el código de trabajo y un ejemplo en línea con el PDF resultante esperado.

El problema :

  1. Como lo indicó Tarsis, cambie FPDF a TFPDF.
  2. De hecho, necesita una fuente que admita los caracteres UTF-8 que está utilizando.

    IE, simplemente usar Helvetica e intentar mostrar japonés no funcionará. Si usa Font Forge, o alguna otra herramienta de fuentes, puede desplazarse hasta los caracteres chinos de la fuente y ver que están en blanco.

    Google tiene una fuente (fuente Noto ) que contiene todos los idiomas, y es de 20 MB, que suele ser varios factores del tamaño de su texto. Entonces, puede ver por qué muchas fuentes simplemente no cubren todos los idiomas.

La solución :

Estoy usando paquetes de fuentes redondeadas-mgenplus-20140828.ttf y ZCOOL_QingKe_HuangYou.ttf para japonés y chino, que son de código abierto y se pueden encontrar en muchos proyectos de código abierto. En tFPDF en sí, o en una nueva clase heredada, como class HTMLtoPDF extends tFPDF {...}, harás esto ...

$this->AddFont('japanese', '', 'rounded-mgenplus-20140828.ttf', true);
$this->SetFont('japanese', '', 14);
$this->Write(14, '日本語');

¡No debería haber nada más!

Paquete de código en GitHub:

https://github.com/HoldOffHunger/php-html-to-pdf

Trabajo, demostración en línea de japonés:

https://www.earthfluent.com/privacy.pdf?language=ja

HoldOffHunger
fuente
1

Para crías.

Cómo logré agregar el idioma ruso a fpdf en mi máquina Linux:

1) Vaya a http://www.fpdf.org/makefont/ y convierta su fuente ttf (por ejemplo, AerialRegular.ttf) en 2 archivos usando la codificación ISO-8859-5 : AerialRegular.php y AerialRegular.z

2) Coloque estos 2 archivos en fpdf / font directorio

3) Úselo en su código:

$pdf = new \FPDI();
    $pdf->AddFont('ArialMT','','ArialRegular.php');
    $pdf->AddPage();
    $tplIdx = $pdf->importPage(1);
    $pdf->useTemplate($tplIdx, 0, 0, 211, 297); //width and height in mms
    $pdf->SetFont('ArialMT','',35);
    $pdf->SetTextColor(255,0,0);
    $fullName = iconv('UTF-8', 'ISO-8859-5', 'Алексей');
    $pdf->SetXY(60, 54);
    $pdf->Write(0, $fullName);
Ryzhak
fuente
0

Puede aplicar esta función en su texto:

 $yourtext = iconv('UTF-8', 'windows-1252', $yourtext);

Gracias

gounane
fuente
0

Utilizo FPDF para ASP y la función iconv no está disponible. Parece extraño, resolví el problema de UTF-8 agregando una imagen falsa (un jpeg de 1x1px) al pdf, justo después de la función AddPage ():

pdf.Image "images/fpdf.jpg",0,0,1

De esta manera, los caracteres acentuados se agregan correctamente a mi pdf, no me pregunten por qué pero funciona.

niente1
fuente
0

No estoy seguro de si funcionará para el griego, pero tuve el mismo problema con los caracteres del portugués brasileño y mi solución fue usar entidades html. Tuve básicamente dos casos:

  1. La cadena puede contener caracteres UTF-8.

Para estos, primero lo codifiqué en entidades html htmlentities()y luego las decodifiqué en iso-8859-1. Ejemplo:

$s = html_entity_decode(htmlentities($my_variable_text), ENT_COMPAT | ENT_HTML401, 'iso-8859-1');
  1. Cadena fija con entidades html:

Para estos, acabo de dejar de htmlentities()llamar. Ejemplo:

$s = html_entity_decode("Treasurer/Tr&eacute;sorier", ENT_COMPAT | ENT_HTML401, 'iso-8859-1');

Luego pasé $sa FPDF, como en este ejemplo:

$pdf->Cell(100, 20, $s, 0, 0, 'L');

Nota: ENT_COMPAT | ENT_HTML401es el valor estándar para el parámetro # 2, como en http://php.net/manual/en/function.html-entity-decode.php

Espero que ayude.

Alexandre Schmidt
fuente
0

Sé que esta pregunta es antigua, pero creo que mi respuesta ayudaría a aquellos que no han encontrado una solución en otras respuestas. Entonces, mi problema era que no podía mostrar caracteres croatas en mi PDF. En primer lugar, usé FPDF pero, creo, no es compatible con Unicode. Finalmente, lo que resolvió mi problema es tFPDF, que es la versión de FPDF que admite Unicode. Este es el ejemplo que funcionó para mí:

require('tFPDF/tfpdf.php');
$pdf = new tFPDF();
$pdf->AddPage();
$pdf->AddFont('DejaVu','','DejaVuSansCondensed.ttf',true);
$pdf->AddFont('DejaVu', 'B', 'DejaVuSansCondensed-Bold.ttf', true);

$pdf->SetFont('DejaVu','',14);

$txt = 'čćžšđČĆŽŠĐ';
$pdf->Write(8,$txt);

$pdf->Output();
Cascanueces
fuente