Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate Pdf from Html string with image and css for android using itext

I am using itext-5.3.4.jar and xmlworker-1.2.1.jar library for generate pdf from html string , html contains image logo and inline css.

My html file and image is in Asset folder , using this library my pdf generating successfully but there is no image display and no css style randering. anyone has a suggestion what should i do to fix this issue, if any other library or any other option for generate pdf from html will be helpful.

I am using these function for generate pdf:

    public static void generatePdfFromHtlm(String fileName, String htmlString){


    try {
        File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), AppConfig.getContext().getPackageName() + "/" + "Pdf");

        if (!mediaStorageDir.exists()) {
            mediaStorageDir.mkdirs();
        }

        File fileWithinMyDir = new File(mediaStorageDir, fileName);

        FontFactory.registerDirectories();
        Document document = new Document(PageSize.A4);
        PdfWriter writer = PdfWriter.getInstance(document,
                new FileOutputStream(fileWithinMyDir));
        document.open();
        HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
        htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
        htmlContext.setImageProvider(new AbstractImageProvider() {
            public String getImageRootPath() {

                Uri uri = Uri.parse("file:///android_asset/");

                String newPath = uri.toString();

                return newPath;
            }
        });


        CSSResolver cssResolver =
                XMLWorkerHelper.getInstance().getDefaultCssResolver(false);
        /*Pipeline<?> pipeline =
                new CssResolverPipeline(cssResolver,
                        new HtmlPipeline(htmlContext,
                                new PdfWriterPipeline(document, writer)));*/

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

        XMLWorker worker = new XMLWorker(css, true);

        XMLParser p = new XMLParser(worker);
        InputStream is = new ByteArrayInputStream(htmlString.getBytes());
        p.parse(is);

        document.close();


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

my html file is

<!DOCTYPE html>
<!--[if IE 8]> <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9]> <html lang="en" class="ie9"> <![endif]-->
<!--[if !IE]><!-->
<html lang="en"> <!--<![endif]-->

<!-- BEGIN HEAD -->
<head>
  <meta charset="utf-8" />
  
  <title>WeighInsheet</title> 
  
  
  <style type="text/css">
  
  body { font-family:Arial; }
      .Wrapper { border:1px solid #cccccc; height:auto; margin:0px 65px;}
      .header { height:105px; margin:5px; float:left;}
      .logo { width:100px; height:100px; float:left; }
  .heading { width:600px;}
  h2{ margin:40px 0px 0px 0px;font-size: 22px; font-weight:bold;}
  h3{ margin:0px; font-weight:normal;font-size: 16px;}
  table { border-collapse: collapse; border-spacing: 0;  width:100%; }
  table td { font-family: arial; font-size: 14px; padding: 10px 5px; border: 1px solid #ddd; }  
  table th { background-color:#000000; color:#ffffff; font-family: arial; font-size: 16px; font-weight: bold;
             border: 1px solid #ddd; }  
  
  </style>


</head>

<!-- END HEAD -->

<!-- BEGIN BODY -->

<body>  
  
<div class="Wrapper">

<div class="header">

<div class="logo"><img src="logo.jpg" class="logo"/></div>

<div class="heading" align="center">
<h2>Description</h2>
<h3>Title Meta</h3>
</div>

</div>
<table>

<thead>
 ##CHANGEHEADER##
</thead>

<tbody>
  ##CHANGEBODY##
</tbody>

</table>

</div>  

</body>

<!-- END BODY -->

</html>

My Image file "logo.jpg" is in asset folder .

like image 909
Rajesh Koshti Avatar asked Jul 01 '26 02:07

Rajesh Koshti


2 Answers

I have Fixed Pdf Generate Issue With Xml Worker class.

For overcome CSS issues i have create external css file and apply it with the html.

For ex.

InputStream is = new ByteArrayInputStream(aHtmlString.getBytes());
                            InputStream css = new ByteArrayInputStream(cssString.getBytes());

                            XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, css);

For Image Display issue copy your image From assets folder to phones internal folder.

Add give your img tag to that folder image path.

For ex.

<img src="/storage/emulated/0/MyApp/Images/my_logo.jpg"/>

Use This methods for copy files from asset to folder.

 public static void listAssetFiles(String path,Context ctx,String folderPath) {

    String [] list;
    try {
        list = ctx.getAssets().list(path);
        if (list.length > 0) {
            // This is a folder
            for (String file : list) {

                copyIntoFolder(file,ctx,path+"/",folderPath);
            }
        }
    } catch (IOException e) {

    }



}

public static void copyIntoFolder(String fileName, Context ctx, String filePath, String folderPath){
    AssetManager assetManager = ctx.getAssets();
    InputStream in = null;
    OutputStream out = null;
    try {
        in = assetManager.open(filePath+fileName);
        File outFile = new File(folderPath , fileName);
        out = new FileOutputStream(outFile);
        Utility.copyFile(in, out);
        in.close();
        // in = null;
        out.flush();
        out.close();
        //out = null;
    } catch(IOException e) {
        Log.e("IOException", "copyIntoFolder: ",e );

    }
}

Itext doesnt support all css properties below is a list of suported css properties, create your html according this supported css properties.

Css Support

like image 50
Rajesh Koshti Avatar answered Jul 02 '26 14:07

Rajesh Koshti


iText Sharp is not supported all css property.You can load html in webview and generate pdf using this code.

private void createWebPrintJob(WebView webView) {

        try {
            PrintDocumentAdapter printAdapter;
            String jobName = getString(R.string.app_name) + " Document";
            PrintAttributes attributes = new PrintAttributes.Builder()
                    .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
                    .setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600))
                    .setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();
            File path = new File(Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/AamirPDF/");


            path.mkdirs();
            PdfPrint pdfPrint = new PdfPrint(attributes);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                printAdapter = webView.createPrintDocumentAdapter(jobName);
            } else {
                printAdapter = webView.createPrintDocumentAdapter();
            }


            pdfPrint.printNew(printAdapter, path, "output_" + System.currentTimeMillis() + ".pdf", getActivity().getCacheDir().getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

PdfPrint class for generate PDF.

package com.example.nisarg.invoice;

import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.util.Log;

import com.example.nisarg.invoice.android.print.ProxyBuilder;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import static com.example.nisarg.invoice.Database.appglobal.context;

public class PdfPrint {

    public static final String TAG = PdfPrint.class.getSimpleName();
    public static PrintAttributes printAttributes;
    File cacheFolder;


    public PdfPrint(PrintAttributes printAttributes) {
        this.printAttributes = printAttributes;
        cacheFolder = new File(context.getFilesDir() + "/etemp/");
    }

    public static PrintDocumentAdapter.WriteResultCallback getWriteResultCallback(InvocationHandler invocationHandler,
                                                                                  File dexCacheDir) throws IOException {
        return ProxyBuilder.forClass(PrintDocumentAdapter.WriteResultCallback.class)
                .dexCache(dexCacheDir)
                .handler(invocationHandler)
                .build();
    }

    public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler,
                                                                                    File dexCacheDir) throws IOException {
        return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class)
                .dexCache(dexCacheDir)
                .handler(invocationHandler)
                .build();
    }

  /*  public void print(final PrintDocumentAdapter printAdapter, final File path, final String fileName) {
        printAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() {
            @Override
            public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {


                try {
                    PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() {
                        @Override
                        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                            if (method.getName().equals("onWriteFinished")) {
                                //                            pdfCallback.onPdfCreated();
                            } else {
                                Log.e(TAG, "Layout failed");
                                //                            pdfCallback.onPdfFailed();
                            }
                            return null;
                        }
                    }, null);

                    printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback);
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
        }, null);
    }*/

    public void printNew(final PrintDocumentAdapter printAdapter, final File path, final String fileName, final String fileNamenew) {

        try {

            printAdapter.onStart();
            printAdapter.onLayout(null, printAttributes, new CancellationSignal(), getLayoutResultCallback(new InvocationHandler() {
                @Override
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {

                    if (method.getName().equals("onLayoutFinished")) {
                        onLayoutSuccess(printAdapter, path, fileName, fileNamenew);
                    } else {
                        Log.e(TAG, "Layout failed");

                    }
                    return null;
                }
            }, new File(fileNamenew)), new Bundle());


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

        }
    }

    private void onLayoutSuccess(PrintDocumentAdapter printAdapter, File path, String fileName, String filenamenew) throws IOException {
        PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                if (method.getName().equals("onWriteFinished")) {

                    System.out.print("hello");

                } else {
                    Log.e(TAG, "Layout failed");

                }
                return null;
            }
        }, new File(filenamenew));
        printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback);
    }

    private ParcelFileDescriptor getOutputFile(File path, String fileName) {
        if (!path.exists()) {
            path.mkdirs();
        }
        File file = new File(path, fileName);
        try {
            file.createNewFile();
            return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
        } catch (Exception e) {
            Log.e(TAG, "Failed to open ParcelFileDescriptor", e);
        }
        return null;
    }
}

Generate Proxy of class.[https://gist.github.com/brettwold/838c092329c486b6112c8ebe94c8007e ]

For dependence which is used in proxy builder class add this line in gradle.

 compile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'
like image 43
MIkka Marmik Avatar answered Jul 02 '26 16:07

MIkka Marmik