com.pablog178.pdfcreator.android.PdfcreatorModule.java Source code

Java tutorial

Introduction

Here is the source code for com.pablog178.pdfcreator.android.PdfcreatorModule.java

Source

/**
 * This file was auto-generated by the Titanium Module SDK helper for Android
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
package com.pablog178.pdfcreator.android;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.io.File;
import java.nio.ByteBuffer;
import java.util.Date;

import org.apache.commons.io.IOUtils;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.titanium.io.TiBaseFile;
import org.appcelerator.titanium.io.TiFileFactory;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.view.TiUIView;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.webkit.WebView;
import android.view.View;
import android.graphics.Paint;

@Kroll.module(name = "Pdfcreator", id = "com.pablog178.pdfcreator.android")
public class PdfcreatorModule extends KrollModule {

    // Standard Debugging variables
    private static final String MODULE_NAME = "PdfcreatorModule";
    private static final String PROXY_NAME = "PDF_PROXY";

    // Private members
    private static TiApplication app;
    private TiUIView view = null;
    private String fileName = "default_name.pdf";
    private int quality = 100;
    private Rectangle pageSize = PageSize.LETTER;

    // You can define constants with @Kroll.constant, for example:
    // @Kroll.constant public static final String EXTERNAL_NAME = value;

    public PdfcreatorModule() {
        super();
    }

    @Kroll.onAppCreate
    public static void onAppCreate(TiApplication myApp) {
        Log.d(MODULE_NAME, "inside onAppCreate");
        app = myApp;
        // put module init code that needs to run when the application is created
    }

    // Methods

    @Kroll.method(runOnUiThread = true)
    public void generateImage(final HashMap args) {
        Log.i(PROXY_NAME, "generateImage()");

        if (TiApplication.isUIThread()) {
            generateImageFunction(args);
        } else {
            app.getCurrentActivity().runOnUiThread(new Runnable() {
                public void run() {
                    generateImageFunction(args);
                }
            });
        }
    }

    @Kroll.method(runOnUiThread = true)
    public void generatePDF(final HashMap args) {
        Log.i(PROXY_NAME, "generatePDF()");

        if (TiApplication.isUIThread()) {
            generateiTextPDFfunction(args);
        } else {
            app.getCurrentActivity().runOnUiThread(new Runnable() {
                public void run() {
                    generateiTextPDFfunction(args);
                }
            });
        }
    }

    //Private functions

    private void generateImageFunction(HashMap args) {
        if (args.containsKey("fileName")) {
            Object fileName = args.get("fileName");
            if (fileName instanceof String) {
                this.fileName = (String) fileName;
                Log.i(PROXY_NAME, "fileName: " + this.fileName);
            }
        } else
            return;

        if (args.containsKey("view")) {
            Object viewObject = args.get("view");
            if (viewObject instanceof TiViewProxy) {
                TiViewProxy viewProxy = (TiViewProxy) viewObject;
                this.view = viewProxy.getOrCreateView();
                if (this.view == null) {
                    Log.e(PROXY_NAME, "NO VIEW was created!!");
                    return;
                }
                Log.i(PROXY_NAME, "view: " + this.view.toString());
            }
        } else
            return;

        TiBaseFile file = TiFileFactory.createTitaniumFile(this.fileName, true);
        Log.i(PROXY_NAME, "file full path: " + file.nativePath());
        try {
            final int PDF_WIDTH = 612;
            final int PDF_HEIGHT = 792;
            Resources appResources = app.getResources();
            OutputStream outputStream = file.getOutputStream();
            int viewWidth = 1600;
            int viewHeight = 1;

            WebView view = (WebView) this.view.getNativeView();

            if (TiApplication.isUIThread()) {

                viewWidth = view.capturePicture().getWidth();
                viewHeight = view.capturePicture().getHeight();

                if (viewWidth <= 0) {
                    viewWidth = 1300;
                }

                if (viewHeight <= 0) {
                    viewHeight = 2300;
                }

            } else {
                Log.e(PROXY_NAME, "NO UI THREAD");
            }

            Log.i(PROXY_NAME, "viewWidth: " + viewWidth);
            Log.i(PROXY_NAME, "viewHeight: " + viewHeight);

            Bitmap viewBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
            float density = appResources.getDisplayMetrics().density;

            Canvas canvas = new Canvas(viewBitmap);
            Matrix matrix = new Matrix();

            Drawable bgDrawable = view.getBackground();
            if (bgDrawable != null) {
                bgDrawable.draw(canvas);
            } else {
                canvas.drawColor(Color.WHITE);
            }
            view.draw(canvas);

            float scaleFactorWidth = 1 / ((float) viewWidth / (float) PDF_WIDTH);
            float scaleFactorHeight = 1 / ((float) viewHeight / (float) PDF_HEIGHT);

            Log.i(PROXY_NAME, "scaleFactorWidth: " + scaleFactorWidth);
            Log.i(PROXY_NAME, "scaleFactorHeight: " + scaleFactorHeight);

            matrix.setScale(scaleFactorWidth, scaleFactorWidth);

            Bitmap imageBitmap = Bitmap.createBitmap(PDF_WIDTH, PDF_HEIGHT, Bitmap.Config.ARGB_8888);
            Canvas imageCanvas = new Canvas(imageBitmap);
            imageCanvas.drawBitmap(viewBitmap, matrix, null);
            imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);

            sendCompleteEvent();

        } catch (Exception exception) {
            Log.e(PROXY_NAME, "Error: " + exception.toString());
            sendErrorEvent(exception.toString());
        }
    }

    private void generateWebArchiveFunction(HashMap args) {
        if (args.containsKey("fileName")) {
            Object fileName = args.get("fileName");
            if (fileName instanceof String) {
                this.fileName = (String) fileName;
                Log.i(PROXY_NAME, "fileName: " + this.fileName);
            }
        } else
            return;

        if (args.containsKey("view")) {
            Object viewObject = args.get("view");
            if (viewObject instanceof TiViewProxy) {
                TiViewProxy viewProxy = (TiViewProxy) viewObject;
                this.view = viewProxy.getOrCreateView();
                if (this.view == null) {
                    Log.e(PROXY_NAME, "NO VIEW was created!!");
                    return;
                }
                Log.i(PROXY_NAME, "view: " + this.view.toString());
            }
        } else
            return;

        try {
            WebView webView = (WebView) this.view.getNativeView();
            webView.saveWebArchive(
                    TiFileFactory.getDataDirectory(true).getAbsolutePath() + File.separator + this.fileName);
            sendCompleteEvent();
        } catch (Exception exception) {
            Log.e(PROXY_NAME, "Error: " + exception.toString());
            sendErrorEvent(exception.toString());
        }
    }

    private void generateiTextPDFfunction(HashMap args) {
        if (args.containsKey("fileName")) {
            Object fileName = args.get("fileName");
            if (fileName instanceof String) {
                this.fileName = (String) fileName;
                Log.i(PROXY_NAME, "fileName: " + this.fileName);
            }
        } else
            return;

        if (args.containsKey("view")) {
            Object viewObject = args.get("view");
            if (viewObject instanceof TiViewProxy) {
                TiViewProxy viewProxy = (TiViewProxy) viewObject;
                this.view = viewProxy.getOrCreateView();
                if (this.view == null) {
                    Log.e(PROXY_NAME, "NO VIEW was created!!");
                    return;
                }
                Log.i(PROXY_NAME, "view: " + this.view.toString());
            }
        } else
            return;

        if (args.containsKey("quality")) {
            this.quality = TiConvert.toInt(args.get("quality"));
        }

        if (args.containsKey("pageSize")) {
            Object pageSize = args.get("pageSize");
            if (pageSize instanceof String) {
                if (pageSize.equals("letter")) {
                    this.pageSize = PageSize.LETTER;
                } else if (pageSize.equals("A4")) {
                    this.pageSize = PageSize.A4;
                } else {
                    this.pageSize = PageSize.LETTER;
                }
            }
        }

        TiBaseFile file = TiFileFactory.createTitaniumFile(this.fileName, true);
        Log.i(PROXY_NAME, "file full path: " + file.nativePath());
        try {

            Resources appResources = app.getResources();
            OutputStream outputStream = file.getOutputStream();
            final int MARGIN = 0;
            final float PDF_WIDTH = this.pageSize.getWidth() - MARGIN * 2; // A4: 595 //Letter: 612
            final float PDF_HEIGHT = this.pageSize.getHeight() - MARGIN * 2; // A4: 842 //Letter: 792
            final int DEFAULT_VIEW_WIDTH = 980;
            final int DEFAULT_VIEW_HEIGHT = 1384;
            int viewWidth = DEFAULT_VIEW_WIDTH;
            int viewHeight = DEFAULT_VIEW_HEIGHT;

            Document pdfDocument = new Document(this.pageSize, MARGIN, MARGIN, MARGIN, MARGIN);
            PdfWriter docWriter = PdfWriter.getInstance(pdfDocument, outputStream);

            Log.i(PROXY_NAME, "PDF_WIDTH: " + PDF_WIDTH);
            Log.i(PROXY_NAME, "PDF_HEIGHT: " + PDF_HEIGHT);

            WebView view = (WebView) this.view.getNativeView();

            if (TiApplication.isUIThread()) {

                viewWidth = view.capturePicture().getWidth();
                viewHeight = view.capturePicture().getHeight();

                if (viewWidth <= 0) {
                    viewWidth = DEFAULT_VIEW_WIDTH;
                }

                if (viewHeight <= 0) {
                    viewHeight = DEFAULT_VIEW_HEIGHT;
                }

            } else {
                Log.e(PROXY_NAME, "NO UI THREAD");
                viewWidth = DEFAULT_VIEW_WIDTH;
                viewHeight = DEFAULT_VIEW_HEIGHT;
            }

            view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            Log.i(PROXY_NAME, "viewWidth: " + viewWidth);
            Log.i(PROXY_NAME, "viewHeight: " + viewHeight);

            float scaleFactorWidth = 1 / ((float) viewWidth / PDF_WIDTH);
            float scaleFactorHeight = 1 / ((float) viewHeight / PDF_HEIGHT);

            Log.i(PROXY_NAME, "scaleFactorWidth: " + scaleFactorWidth);
            Log.i(PROXY_NAME, "scaleFactorHeight: " + scaleFactorHeight);

            Bitmap viewBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
            Canvas viewCanvas = new Canvas(viewBitmap);

            // Paint paintAntialias = new Paint();
            // paintAntialias.setAntiAlias(true);
            // paintAntialias.setFilterBitmap(true);

            Drawable bgDrawable = view.getBackground();
            if (bgDrawable != null) {
                bgDrawable.draw(viewCanvas);
            } else {
                viewCanvas.drawColor(Color.WHITE);
            }
            view.draw(viewCanvas);

            TiBaseFile pdfImg = createTempFile();

            // ByteArrayOutputStream stream = new ByteArrayOutputStream(32);
            // viewBitmap.compress(Bitmap.CompressFormat.JPEG, this.quality, stream);
            viewBitmap.compress(Bitmap.CompressFormat.JPEG, this.quality, pdfImg.getOutputStream());

            FileInputStream pdfImgInputStream = new FileInputStream(pdfImg.getNativeFile());
            byte[] pdfImgBytes = IOUtils.toByteArray(pdfImgInputStream);
            pdfImgInputStream.close();

            // ByteBuffer      buffer         = ByteBuffer.allocate(viewBitmap.getByteCount());
            // viewBitmap.copyPixelsToBuffer(buffer);

            pdfDocument.open();
            float yFactor = viewHeight * scaleFactorWidth;
            int pageNumber = 1;

            do {
                if (pageNumber > 1) {
                    pdfDocument.newPage();
                }
                pageNumber++;
                yFactor -= PDF_HEIGHT;

                Image pageImage = Image.getInstance(pdfImgBytes, true);
                // Image pageImage = Image.getInstance(buffer.array());
                pageImage.scalePercent(scaleFactorWidth * 100);
                pageImage.setAbsolutePosition(0f, -yFactor);
                pdfDocument.add(pageImage);

                Log.i(PROXY_NAME, "yFactor: " + yFactor);
            } while (yFactor > 0);

            pdfDocument.close();

            sendCompleteEvent();

        } catch (Exception exception) {
            Log.e(PROXY_NAME, "Error: " + exception.toString());
            sendErrorEvent(exception.toString());
        }
    }

    // method to invoke success callback
    private void sendCompleteEvent() {
        if (this.hasListeners("complete")) {
            KrollDict props = new KrollDict();
            props.put("fileName", this.fileName);
            this.fireEvent("complete", props);
        }
    }

    // method to invoke error callback
    private void sendErrorEvent(String message) {
        if (this.hasListeners("error")) {
            KrollDict props = new KrollDict();
            props.put("message", message);
            this.fireEvent("error", props);
        }
    }

    private TiBaseFile createTempFile() {
        String fileName = Long.toString(new Date().getTime()) + ".png";
        TiBaseFile file = TiFileFactory.createTitaniumFile(this.fileName, true);
        file.getNativeFile().deleteOnExit();

        return file;
    }
}