Da HTML a PDF con immagini base64 genera FileNotFoundException

Sto usando itextpdf-5.0.6.jar (Java 8) e quando provo ad esportare il codice html con il tag immagine base64 ottengo l’eccezione di file non trovata.

se rimuovo il tag immagine tutto funziona alla grande!

Ho trovato poche soluzioni sull’overriding del processore di tag di immagine, ma la maggior parte di esse sono vecchie e non compatiable con la versione 5.0.6.

Ecco l’HTML che invio:

"\n\n\n \n Test PDF\n\n\n\n 
\n\n \n\n\n
\n\n
\n
\nHellow world
\n"

parte del mio codice:

 fileOutputStream = new FileOutputStream(file); Document document = new Document(); PdfWriter.getInstance(document, fileOutputStream); document.open(); HTMLWorker htmlWorker = new HTMLWorker(document); StringReader stringReader = new StringReader(htmlCode); htmlWorker.parse(stringReader); document.close(); fileOutputStream.close(); 

ogni aiuto sarà appicato grazie

HTMLWorker usare HTMLWorker , come ripetuto molte volte su StackOverflow, la class HTMLWorker è stata abbandonata a favore di XML Worker molto tempo fa. Non investiremo nell’ulteriore sviluppo di HTMLWorker quindi è una pessima scelta usarlo. Passare a XML Worker.

Anche l’aggiornamento alla versione più recente di iText, la versione che stai usando risale al 4 febbraio 2011 , molti bug sono stati corretti nei 4 anni passati. Assicurati di avere sia il jar iText che il jar XML Worker con lo stesso numero di versione.

Le immagini Base64 non sono ancora supportate, ma ti ho reso una semplice Prova di concetto, che mostra quanto sia facile aggiungere supporto per tali immagini. Dai un’occhiata all’esempio ParseHtml4 e al PDF risultante: html_4.pdf .

Per ottenere ciò, è necessario scrivere un’implementazione dell’interfaccia ImageProvider . Ho fatto questo estendendo la class AbstractImageProvider :

 class Base64ImageProvider extends AbstractImageProvider { @Override public Image retrieve(String src) { int pos = src.indexOf("base64,"); try { if (src.startsWith("data") && pos > 0) { byte[] img = Base64.decode(src.substring(pos + 7)); return Image.getInstance(img); } else { return Image.getInstance(src); } } catch (BadElementException ex) { return null; } catch (IOException ex) { return null; } } @Override public String getImageRootPath() { return null; } } 

Come puoi vedere, controllo l’esistenza di "base64," in tutto ciò che viene passato a XML Worker tramite l’attributo src del tag img . Se quella String è presente, decodifico ciò che segue "base64," e restituisco un object Image che viene creato utilizzando i byte risultanti.

Una volta che hai implementato ImageProvider , è solo questione di passarlo a XML Worker.