Generate PDF from HTML String in Android or Convert HTML to PDF using Webview in Android.

1) Create a package in your App Java folder with the name android.print

2) In that package create PdfConverter class.


package android.print;

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.File;

public class PdfConverter implements Runnable {

    private static final String TAG = "PdfConverter";
    private static PdfConverter sInstance;

    private Context mContext;
    private String mHtmlString;
    private File mPdfFile;
    private PrintAttributes mPdfPrintAttrs;
    private boolean mIsCurrentlyConverting;
    private WebView mWebView;
    OnPDFCreated mOnPDFCreated;

    private PdfConverter() {
    }

    public static synchronized PdfConverter getInstance() {
        if (sInstance == null)
            sInstance = new PdfConverter();

        return sInstance;
    }


    public void SetOnPDFCreatedListener(OnPDFCreated OnPDFCreated) {
        this.mOnPDFCreated = OnPDFCreated;
    }

    @Override
    public void run() {
        mWebView = new WebView(mContext);

        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setDomStorageEnabled(true);
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.getSettings().setLoadsImagesAutomatically(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
                    throw new RuntimeException("call requires API level 19");
                else {
                    PrintDocumentAdapter documentAdapter = null;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        documentAdapter = mWebView.createPrintDocumentAdapter("Document");
                    }else {
                        documentAdapter = mWebView.createPrintDocumentAdapter();
                    }

                    documentAdapter.onLayout(null, getPdfPrintAttrs(), null, new PrintDocumentAdapter.LayoutResultCallback() {
                    }, null);
                    documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFileDescriptor(), null, new PrintDocumentAdapter.WriteResultCallback() {
                        @Override
                        public void onWriteFinished(PageRange[] pages) {
                            Log.e("onWriteFinished", "onWriteFinished call");
                            if (mOnPDFCreated != null){
                                mOnPDFCreated.onPDFCreated();
                            }
                            destroy();
                        }
                    });
                }
            }
        });

        mWebView.loadDataWithBaseURL("",mHtmlString, "text/HTML", "UTF-8","");
    }

    private PrintAttributes getPdfPrintAttrs() {
        return mPdfPrintAttrs != null ? mPdfPrintAttrs : getDefaultPrintAttrs();
    }

    public void setPdfPrintAttrs(PrintAttributes printAttrs) {
        this.mPdfPrintAttrs = printAttrs;
    }

    public void convert(Context context, String htmlString, File file) {
        if (context == null)
            throw new IllegalArgumentException("context can't be null");
        if (htmlString == null)
            throw new IllegalArgumentException("htmlString can't be null");
        if (file == null)
            throw new IllegalArgumentException("file can't be null");

        if (mIsCurrentlyConverting)
            return;

        mContext = context;
        mHtmlString = htmlString;
        mPdfFile = file;
        mIsCurrentlyConverting = true;
        runOnUiThread(this);
    }

    private ParcelFileDescriptor getOutputFileDescriptor() {
        try {
            mPdfFile.createNewFile();
            return ParcelFileDescriptor.open(mPdfFile, ParcelFileDescriptor.MODE_TRUNCATE | ParcelFileDescriptor.MODE_READ_WRITE);
        } catch (Exception e) {
            Log.d(TAG, "Failed to open ParcelFileDescriptor", e);
        }
        return null;
    }

    private PrintAttributes getDefaultPrintAttrs() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null;

        return new PrintAttributes.Builder()
                .setMediaSize(PrintAttributes.MediaSize.NA_GOVT_LETTER)
                .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
                .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
                .build();

    }

    private void runOnUiThread(Runnable runnable) {
        Handler handler = new Handler(mContext.getMainLooper());
        handler.post(runnable);
    }

    private void destroy() {
        mContext = null;
        mHtmlString = null;
        mPdfFile = null;
        mPdfPrintAttrs = null;
        mIsCurrentlyConverting = false;
        mWebView = null;
    }


    public interface OnPDFCreated {

        void onPDFCreated();

    }

}


3)
       YourFilePath Example:-

     /storage/emulated/0/PDF Example/Example_PDF_File.pdf

       PdfConverter converter = PdfConverter.getInstance();
                converter.convert(this, YourHTMLString,
                        new File(YourFilePath);

                converter.SetOnPDFCreatedListener(new OnPDFCreated() {

                    @Override
                    public void OnPDFCreated() {
                                // Here you can open the PDF file.

                     
                    }
                }); 

Comments

Post a Comment

Popular posts from this blog

Error:java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant). at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:240) at com.google.android.material.internal.ThemeEnforcement.checkMaterialTheme(ThemeEnforcement.java:215) at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:143) at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:78) at com.google.android.material.chip.ChipDrawable.loadFromAttributes(ChipDrawable.java:359) at com.google.android.material.chip.ChipDrawable.createFromAttributes(ChipDrawable.java:292) at com.google.android.material.chip.Chip.(Chip.java:193) at com.google.android.material.chip.Chip.(Chip.java:186) at com.google.android.material.chip.Chip.(Chip.java:182) at com.demo.nspl.restaurantlite.Navigation_Drawer.SalesFragment.getFilterChip(SalesFragment.java:158) at com.demo.nspl.restaurantlite.Navigation_Drawer.SalesFragment.lambda$onCreateView$0(SalesFragment.java:71) at com.demo.nspl.restaurantlite.Navigation_Drawer.-$$Lambda$SalesFragment$KCm-iiczjdYbpiNmaNw12gtFOoQ.onClick(lambda) at android.view.View.performClick(View.java:5268) at android.view.View$PerformClick.run(View.java:21550) at android.os.Handler.handleCallback(Handler.java:822) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5811) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)

Get Two digit after decimal point in Android or Java

Configuration 'androidTestCompile' is obsolete and has been replaced with 'androidTestImplementation' and 'androidTestApi'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html Configuration 'androidTestApi' is obsolete and has been replaced with 'androidTestImplementation'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html Configuration 'testCompile' is obsolete and has been replaced with 'testImplementation' and 'testApi'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html Configuration 'testApi' is obsolete and has been replaced with 'testImplementation'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html