4

I am working with iTextPdf (iTextG for Android)library to convert Html to PDF document for my android application. Everything is working fine for me except the logo on the receipt. My html contains <img> tag with the source http url for the image

<img src="http...."></img>

created pdf is not having the image. Same code and html running in my Java app is showing logo with created PDF (This shows there is no issue with accessing the image). I am wondering if this feature is only compatible with Java but not with the Android? I am using using following dependencies:

compile 'com.itextpdf:itextg:5.5.10'
compile 'com.itextpdf.tool:xmlworker:5.5.10'

Html Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="English">
<head>
    <title>Title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
</head>

<body>
<img src="https://image.flaticon.com/teams/slug/google.jpg"></img>
<h1>Fischerstube</h1>
</body>
</html>

Function in Main Activity:

 private void htmlToPdf(String html) throws DocumentException, IOException {

    try {

        File file = new File(Environment.getExternalStorageDirectory() + File.separator + "logo.pdf");
        OutputStream fileOutputStream = new FileOutputStream(file);
        Document document = new Document();
        document.setPageSize(new Rectangle(201,720));
        PdfWriter writer = PdfWriter.getInstance(document, fileOutputStream);
        document.open();
        InputStream is = new ByteArrayInputStream(html.getBytes());
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
        document.close();
        fileOutputStream.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Its only rendering <h1> tag and shows Fischerstube but no image on ANDROIRD DEVICE. Can any one help me in this regard, will be grateful.

Salman Nazir
  • 2,759
  • 2
  • 28
  • 42
  • 1
    The versions of iTextG and XMLWorker have to be the same. – Amedee Van Gasse Dec 20 '17 at 20:06
  • @AmedeeVanGasse: I checked with 5.5.10 for both xmlworker and itextg and got same behaviour (No image). I shouldn't be issue as this combination is working fine on Java but on in Android. – Salman Nazir Dec 21 '17 at 16:20
  • @AmedeeVanGasse Please check I just updated the information what I am using in Android. – Salman Nazir Jan 02 '18 at 17:03
  • It looks like your Android device either doesn't allow access to external resources, or it allows access, but downloading the image times out. Also: your customers might be very angry with you if you provide them an app that seriously increases their data usage bill. – Bruno Lowagie Jan 03 '18 at 15:48

1 Answers1

0

Looking at the documentation provided here solved for me.

make sure you have Internet permission in the manifest.

create Base64ImageProvider class

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;
    }
}

Then call create pdf method to convert yout HTML to pdf

public void createPdf() throws IOException, DocumentException {
    String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
            "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"English\">\n" +
            "<head>\n" +
            "    <title>Title</title>\n" +
            "    <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n" +
            "</head>\n" +
            "\n" +
            "<body>\n" +
            "<img src=\"https://image.flaticon.com/teams/slug/google.jpg\"></img>\n" +
            "<h1>Fischerstube</h1>\n" +
            "</body>\n" +
            "</html>";


    // step 1
    File file = new File(Environment.getExternalStorageDirectory() + File.separator + "logo.pdf");
    OutputStream fileOutputStream = new FileOutputStream(file);
    Document document = new Document();
    // step 2
    PdfWriter writer = PdfWriter.getInstance(document, fileOutputStream);
    // step 3
    document.open();
    // step 4

    // CSS
    CSSResolver cssResolver =
            XMLWorkerHelper.getInstance().getDefaultCssResolver(true);

    // HTML
    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    htmlContext.setImageProvider(new Base64ImageProvider());

    // Pipelines
    PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
    HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
    CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

    // XML Worker
    XMLWorker worker = new XMLWorker(css, true);
    XMLParser p = new XMLParser(worker);
    p.parse(new ByteArrayInputStream(str.getBytes()));

    // step 5
    document.close();
}

Make sure you execute createPdf method on background thread. since you will be performing network operation.

Gautam Chibde
  • 1,167
  • 3
  • 14
  • 27