Imansible ottenere caratteri cechi durante la generazione di un PDF

Ho un problema durante l’aggiunta di caratteri come “Č” o “Ć” durante la generazione di un PDF. Sto principalmente usando i paragrafi per inserire del testo statico nel mio rapporto PDF. Ecco alcuni esempi di codice che ho usato:

var document = new Document(); document.Open(); Paragraph p1 = new Paragraph("Testing of letters Č,Ć,Š,Ž,Đ", new Font(Font.FontFamily.HELVETICA, 10)); document.Add(p1); 

L’output che ottengo quando viene generato il file PDF è simile al seguente: “Test delle lettere ,, Š, Ž, Đ”

Per qualche ragione, iTextSharp non sembra riconoscere queste lettere come “Č” e “Ć”.

IL PROBLEMA:

Prima di tutto, non sembra che si parli di caratteri cirillici, ma di lingue dell’Europa centrale e orientale che utilizzano la scrittura latina. Dai un’occhiata alla differenza tra la code page 1250 e la code page 1251 per capire cosa intendo. [NOTA: ho aggiornato la domanda in modo che parli di caratteri cechi anziché cirillici.]

Seconda osservazione. Stai scrivendo il codice che contiene caratteri speciali:

 "Testing of letters Č,Ć,Š,Ž,Đ" 

Questa è una ctriggers pratica. I file di codice sono memorizzati come testo normale e possono essere salvati utilizzando diverse codifiche. Un passaggio accidentale dalla codifica (ad esempio: caricandolo su un sistema di controllo delle versioni che utilizza una codifica diversa), può danneggiare seriamente il contenuto del file.

Dovresti scrivere un codice che non contenga caratteri speciali, ma che usi una notazione diversa. Per esempio:

 "Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110" 

Ciò assicurerà inoltre che il contenuto non venga modificato durante la compilazione del codice utilizzando un compilatore che si aspetta una codifica diversa.

Il tuo terzo errore è che tu pensi che Helvetica sia un font che sa come disegnare questi glifi. Questa è una falsa ipotesi. Dovresti usare un file font come Arial.ttf (o scegliere qualsiasi altro font che sappia come disegnare questi glifi).

Il tuo quarto errore è che non incorpori il carattere. Supponiamo che tu usi un font che hai sul tuo computer locale e che sia in grado di disegnare glifi speciali, quindi sarai in grado di leggere il testo sul tuo computer locale. Tuttavia, qualcuno che riceve il file, ma non ha il carattere che hai usato sul suo computer locale, potrebbe non essere in grado di leggere correttamente il documento.

Il tuo quinto errore è che non hai definito una codifica quando usi il font (questo è legato al tuo secondo errore, ma è diverso).

LA SOLUZIONE:

Ho scritto un piccolo esempio chiamato CzechExample che risulta nel seguente PDF: czech.pdf

inserisci la descrizione dell'immagine qui

Ho aggiunto lo stesso testo due volte, ma usando una codifica diversa:

 public static final String FONT = "resources/fonts/FreeSans.ttf"; public void createPdf(String dest) throws IOException, DocumentException { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream(DEST)); document.open(); Font f1 = FontFactory.getFont(FONT, "Cp1250", true); Paragraph p1 = new Paragraph("Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110", f1); document.add(p1); Font f2 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, true); Paragraph p2 = new Paragraph("Testing of letters \u010c,\u0106,\u0160,\u017d,\u0110", f2); document.add(p2); document.close(); } 

Per evitare il tuo terzo errore, ho usato il carattere FreeSans.ttf invece di Helvetica. È ansible scegliere qualsiasi altro font purché supporti i caratteri che si desidera utilizzare. Per evitare il tuo quarto errore, ho impostato il parametro embedded su true .

Per quanto riguarda il tuo quinto errore, ho introdotto due approcci diversi.

Nel primo caso, ho detto a iText di usare la code page 1250.

 Font f1 = FontFactory.getFont(FONT, "Cp1250", true); 

Questo incorporerà il carattere come un semplice carattere nel PDF, nel senso che ogni carattere nella String verrà rappresentato utilizzando un singolo byte . Il vantaggio di questo approccio è la semplicità; lo svantaggio è che non si dovrebbe iniziare a mescolare le code page. Ad esempio: questo non funzionerà con i glifi cirillici.

Nel secondo caso, ho detto a iText di usare Unicode per la scrittura orizzontale:

 Font f2 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, true); 

Questo incorporerà il carattere come carattere composito nel PDF, il che significa che ogni carattere nella String verrà rappresentato utilizzando più di un byte . Il vantaggio di questo approccio è che è l’approccio raccomandato nei nuovi standard PDF (ad esempio PDF / A, PDF / UA) e che è ansible combinare il cirillico con il latino, il cinese con il giapponese, ecc … Lo svantaggio è che tu creare più byte, ma tale effetto è limitato dal fatto che i flussi di contenuto sono comunque compressi.

Quando eseguo la decompressione del stream di contenuti per il testo nel PDF di esempio, vedo la seguente syntax PDF:

inserisci la descrizione dell'immagine qui

Come ho spiegato, i singoli byte vengono utilizzati per memorizzare il testo della prima riga. I doppi byte vengono utilizzati per memorizzare il testo della seconda riga.

Potresti essere sorpreso dal fatto che questi personaggi sembrano OK all’esterno (quando guardi il testo in Adobe Reader), ma non corrispondono a ciò che vedi all’interno (quando guardi la seconda schermata), ma è così che funziona .

CONCLUSIONE:

Molte persone pensano che la creazione di PDF sia banale e che gli strumenti per la creazione di PDF dovrebbero essere una merce. In realtà, non è sempre così semplice 😉