Kodowanie FPDF UTF-8 (JAK ZROBIĆ)

80

Czy ktoś wie jak ustawić kodowanie w pakiecie FPDF na utf-8? Lub przynajmniej ISO-8859-7 (grecki), który obsługuje greckie znaki?

Zasadniczo chcę utworzyć plik pdf zawierający greckie znaki.

Wszelkie sugestie byłyby pomocne. Jerzy

yorgos
źródło
Jeśli chcesz używać większej liczby języków, potrzebujesz UTF8, więc możesz użyć tFPDF. Spójrz na pakiet Composer .
robsch

Odpowiedzi:

116

Nie używaj kodowania UTF-8. Standardowe czcionki FPDF używają ISO-8859-1 lub Windows-1252. Możliwe jest wykonanie konwersji do ISO-8859-1 z utf8_decode(): $str = utf8_decode($str); Jednak niektóre znaki, takie jak Euro, nie zostaną poprawnie przetłumaczone. Jeśli rozszerzenie iconv jest dostępne, właściwy sposób jest następujący: $str = iconv('UTF-8', 'windows-1252', $str);

Michał
źródło
22
Myślę, że to nie pomoże. Twoja odpowiedź wyjaśnia, jak wygenerować plik PDF z kodowaniem ISO-8859-1 lub Windows-1252, ale te kodowania nie będą działać w językach innych niż łacińskie. Nie wspominając o tworzeniu tekstów wielojęzycznych (zawierających wiele skryptów).
Томица Кораћ
3
@Rafiq: nie używaj "starego" FPDF, ale nowszej wersji tFPDF UTF8 jako postetu w mojej odpowiedzi.
Tarsis
1
Uwaga: przy korzystaniu z ISO-8859-1 znak € nie będzie działał (w zestawie znaków nie ma znaku Euro, zamiast tego użyj ISO-8859-15).
BurninLeo
1
@BurninLeo: ISO-8859-15 nie jest dużo lepsze, wszystkie te kodowania mają ten sam limit znaków, więc -15 ma €, ale dlatego brakuje ´ lub ½. Jedynym prawdziwym rozwiązaniem jest użycie UTF-8 zamiast jego unikania - jak pokazano w mojej odpowiedzi.
Tarsis
3
tFPDF obsługuje Unicode, ale nie był aktualizowany od 3 lat, podczas gdy FPDF został ostatnio zaktualizowany, czyniąc tFPDF przestarzałym. Należy o tym pamiętać podczas korzystania z tFPDF.
Agilis
38

Istnieje również oficjalna wersja FPDF UTF-8 o nazwie tFPDF http://www.fpdf.org/en/script/script92.php

Możesz łatwo przełączyć się z oryginalnego FPDF, po prostu upewnij się, że używasz również czcionki Unicode, jak pokazano w przykładzie w powyższym linku lub moim kodzie:

<?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");

//...
?>

Myślę, że bardziej eleganckie jest używanie tego zamiast rozsyłania wszędzie utf8_decode (), a możliwość używania plików .ttf bezpośrednio w AddFont () jest również zaletą.

Każda inna odpowiedź to tylko sposób na uniknięcie lub obejście problemu, a unikanie UTF-8 nie jest prawdziwą opcją dla aktualnego projektu.

Istnieją również alternatywy, takie jak mPDF lub TCPDF (i inne), które opierają się na FPDF, ale oferują zaawansowane funkcje, obsługują UTF-8 i mogą interpretować kod HTML (oczywiście ograniczone, ponieważ nie ma bezpośredniego sposobu konwersji HTML do PDF). Większość kodu FPDF może być używana bezpośrednio w tych bibliotekach, więc migracja kodu jest dość łatwa.

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

Tarsis
źródło
1
Żadne z rozwiązań iconv i decode nie działa dla bardziej wyjątkowych postaci (♠ ♥ ☺äκόσμος). Ale jeśli po prostu zastąpisz swój fpdf.php plikiem tpdf.php, wszystko zacznie działać, a Twoje pliki staną się mniejsze jako dodatkowy bonus. Świetna poprawka.
Sebastian
1
Czy FPDF i tFPDF są oddzielnymi oddziałami? Czy ktoś wie, dlaczego tFPDF jest tak dobrze ukryty na stronie FPDF? Czy są jakieś wady, o których warto wiedzieć przed zmianą?
BurninLeo,
1
Jestem pewien, dlaczego nie zrobili tego domyślną wersją FPDF, ale jest ona połączona bezpośrednio na stronie głównej fpdf.org i jak wspomniano tam, funkcje tFPDF zostały pierwotnie opracowane dla mPDF. Użyłem tFPDF do wielu plików PDF w produktywnym środowisku i myślę, że oprócz UTF-8 i zmian czcionek jest w 100% taki sam. Nigdy nie miałem żadnych problemów.
Tarsis
1
tFPDF to skrypt lub rozszerzenie FPDF. Jest uważany za przestarzały (zaktualizowany 3 lata temu), ponieważ FPDF został ostatnio zaktualizowany. Autor tFPDF nie utrzymuje go w utrzymaniu, a GitHub powiązany z tFPDF nie został dotknięty. Zobacz: github.com/rev42/tfpdf
Agilis
Tak długo, jak nie potrzebujesz więcej funkcji, nie widzę w tym problemu, przy okazji ostatnia (drobna) aktualizacja miała miejsce zaledwie 4 miesiące temu - wciąż lepsze niż brak obsługi UTF-8. Tak czy inaczej, wolałbym TCPDF lub mPDF, które opierają się na FPDF, ale zapewniają zaawansowane funkcje, a także obsługują kod HTML.
Tarsis
28

istnieje naprawdę proste rozwiązanie tego problemu.

W pliku fpdf.php przejdź do wiersza, który mówi:

if($txt!=='')
{

To wiersz 648 w mojej wersji fpdf. Wstaw następujący wiersz kodu:

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

(nad linią kodu)

if($align=='R')

Działa to dla wszystkich niemieckich znaków specjalnych i powinno również działać dla greckich znaków specjalnych. W przeciwnym razie po prostu zamień cp1252 na odpowiedni alfabet, którego potrzebujesz. Możesz zobaczyć wszystkie obsługiwane znaki tutaj: http://en.wikipedia.org/wiki/Windows-1252

Widziałem rozwiązanie tutaj: http://fudforum.org/forum/index.php?t=msg&goto=167345 Proszę użyć mojego przykładowego kodu powyżej, ponieważ oryginalny autor zapomniał wstawić myślnik między utf a 8.

Mam nadzieję, że powyższe było pomocne.

Daan

Daan
źródło
Idealnie, to nadal działa lub jest potrzebne po aktualizacji FPDF do wersji obsługującej PHP7, aby poprawnie wyświetlać znaki specjalne.
Aren
1
To polecenie działa dla mnie, $ txt = iconv ('utf-8', 'cp1252', $ txt); Dzięki
Patrick Arguello
Po prostu niesamowite proste rozwiązanie. Smutne, że jest schowany w nieznanym miejscu na stackoverflow :)
Pieter-Jan Casteels
To zmieniło coś w moich odstępach - niektóre linie przerywają się wcześniej. Ale przynajmniej wydaje się, że działa - zanim list turecki w ogóle mi nie działał, teraz przynajmniej coś widzę.
Cold_Class,
9

Najpierw musisz wygenerować czcionkę. Należy użyć MakeFontnarzędzia zawartego w pakiecie FPDF. Użyłem w Linuksie tego nieco rozszerzonego skryptu z wersji demonstracyjnej:

<?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');
}
?>

Następnie skopiowałem wygenerowane pliki do fontkatalogu mojej sieci i użyłem tego:

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

(Pracowałem na stole). To działało w moim języku ( Buňka jedna to czes. Cell one ). Język czeski należy do języków środkowoeuropejskich, również ISO-8859-2. Niestety, użytkownik FPDF jest zmuszony do utraty zalet kodowania UTF-8. Nie możesz tego dostać w swoim pliku PDF:

Městečko Fruens Bøge

Duńska litera østaje się řISO-8859-2.

Sugestia rozwiązania: Musisz zdobyć czcionkę grecką, wygenerować czcionkę za pomocą odpowiedniego kodowania (ISO-8859-7) i używać iconvtego samego kodowania docelowego, z którym została wygenerowana czcionka.

Theodor Keinstein
źródło
4

Żadne z powyższych rozwiązań nie zadziała.

Spróbuj tego:

function filter_html($value){
    $value = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
    return $value;
}
Ankit Shukla
źródło
4

Możesz utworzyć klasę rozszerzającą FPDF i dodać to:

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
źródło
4

Chciałem odpowiedzieć na to pytanie każdemu, kto nie przeszedł na TFPDF z jakiegokolwiek powodu (integracja frameworka itp.)

Idź do: http://www.fpdf.org/makefont/index.php

Użyj .ttfkompatybilnej czcionki dla języka, którego chcesz używać. Upewnij się, że wybrałeś numer kodowania odpowiedni dla Twojego języka. Pobierz pliki i wklej je do bieżącego katalogu czcionek FPDF.

Użyj tego, aby aktywować nową czcionkę: $pdf->AddFont($font_name,'','Your_Font_Here.php');

Wtedy możesz $pdf->SetFontnormalnie używać .

Na samej czcionce użyj iconv, aby przekonwertować na UTF-8. Więc jeśli na przykład używasz hebrajskiego, zrobisz to iconv('UTF-8', 'windows-1255', $first_name).

Zastąp numer kodowania systemu Windows kodowaniem swojego języka.

W przypadku strony od prawej do lewej szybką naprawą jest zrobienie czegoś takiego strrev(iconv('UTF-8', 'windows-1255', $first_name)).

rozick
źródło
4

po prostu wyedytuj komórkę funkcji w pliku fpdf.php, poszukaj linii, która wygląda następująco

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

po znalezieniu linii

napisz po {,

$txt = utf8_decode($txt);

zapisz plik i gotowe, akcenty i kodowanie utf8 będą działać :)

R.Costa
źródło
3

Jak utworzyć pliki PDF w FPDF, które obsługują język chiński, japoński, rosyjski itp.?

(migawki używanego kodu poniżej)

Chciałbym podać: podsumowanie problemu, rozwiązanie, projekt github z działającym kodem oraz przykład online z oczekiwanym, wynikowym plikiem PDF.

Problem :

  1. Jak stwierdził Tarsis, zamień FPDF na TFPDF.
  2. W rzeczywistości potrzebujesz czcionki, która obsługuje używane znaki UTF-8.

    IE, samo używanie Helvetica i próba wyświetlenia japońskiego nie zadziała. Jeśli używasz Font Forge lub innego narzędzia do obsługi czcionek, możesz przewinąć do chińskich znaków czcionki i sprawdzić, czy są puste.

    Google ma czcionkę (czcionkę Noto ), która zawiera wszystkie języki i jest to 20 MB, co zwykle stanowi kilka czynników wielkości tekstu. Możesz więc zobaczyć, dlaczego wiele czcionek po prostu nie obejmuje wszystkich języków.

Rozwiązanie :

Używam pakietów czcionek rounded-mgenplus-20140828.ttf i ZCOOL_QingKe_HuangYou.ttf dla języka japońskiego i chińskiego, które są open source i można je znaleźć w wielu projektach open source. W samym tFPDF lub nowej jego klasie dziedziczącej, na przykład class HTMLtoPDF extends tFPDF {...}, zrobisz to ...

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

Nie powinno być nic więcej!

Pakiet kodu na GitHub:

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

Działa, Demo online języka japońskiego:

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

HoldOffHunger
źródło
1

Dla potomstwa.

Jak udało mi się dodać język rosyjski do fpdf na moim komputerze z systemem Linux:

1) Przejdź do http://www.fpdf.org/makefont/ i przekonwertuj swoją czcionkę ttf (na przykład AerialRegular.ttf) do 2 plików przy użyciu kodowania ISO-8859-5 : AerialRegular.php i AerialRegular.z

2) Umieść te 2 pliki w fpdf / font katalogu

3) Użyj go w swoim kodzie:

$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
źródło
0

Możesz zastosować tę funkcję do swojego tekstu:

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

Dzięki

gounane
źródło
0

Używam FPDF dla ASP, a funkcja iconv nie jest dostępna. Wydaje się to dziwne, ponieważ rozwiązałem problem UTF-8, dodając fałszywy obraz (jpeg 1x1px) do pliku PDF, zaraz po funkcji AddPage ():

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

W ten sposób znaki akcentowane są poprawnie dodawane do mojego pliku PDF, nie pytaj mnie dlaczego, ale to działa.

niente1
źródło
0

Nie jestem pewien, czy to wystarczy dla greckiego, ale miałem ten sam problem ze znakami brazylijskiego portugalskiego i moim rozwiązaniem było użycie encji html. Miałem w zasadzie dwa przypadki:

  1. Ciąg może zawierać znaki UTF-8.

W tym celu najpierw zakodowałem go do jednostek html, htmlentities()a następnie zdekodowałem do iso-8859-1. Przykład:

$s = html_entity_decode(htmlentities($my_variable_text), ENT_COMPAT | ENT_HTML401, 'iso-8859-1');
  1. Naprawiono ciąg znaków z encjami html:

W tym celu po prostu htmlentities()zawołałem. Przykład:

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

Następnie przeszedłem $sdo FPDF, jak w tym przykładzie:

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

Uwaga: ENT_COMPAT | ENT_HTML401to standardowa wartość parametru nr 2, jak w http://php.net/manual/en/function.html-entity-decode.php

Mam nadzieję, że to pomoże.

Alexandre Schmidt
źródło
0

Wiem, że to stare pytanie, ale myślę, że moja odpowiedź pomogłaby tym, którzy nie znaleźli rozwiązania w innych odpowiedziach. Mój problem polegał na tym, że nie mogłem wyświetlić chorwackich znaków w moim pliku PDF. Po pierwsze, użyłem FPDF, ale myślę, że nie obsługuje Unicode. Wreszcie, tym, co rozwiązało mój problem, jest tFPDF, czyli wersja FPDF obsługująca Unicode. Oto przykład, który zadziałał dla mnie:

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();
Orzechówka
źródło