Powered By Blogger
Showing posts with label printing. Show all posts
Showing posts with label printing. Show all posts

Thursday, August 25, 2011

Printing with JEditorPane

The following is an illustration of printing with Java. Here I have used JEditorPane and PrinterJob. What printed in this example is an html page.

===================================================================


package ds.demo.service;

import java.awt.print.PrinterJob;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;

import javax.swing.JEditorPane;

public class Test {

    static MessageFormat head = new MessageFormat("");
    static MessageFormat foot = new MessageFormat("");

    public static void main(String[] args) throws Exception {

        PrinterJob pj = PrinterJob.getPrinterJob();
        if(pj.printDialog()) {
            JEditorPane text = new JEditorPane("text/html", "text");
//            text.setText("Return this page to Shyarmal.");
            text.read(new BufferedReader(new InputStreamReader(new FileInputStream(new File("a.html")))), "");
            text.repaint();
            pj.setPrintable(text.getPrintable(head, foot));
            pj.print();
            System.out.println("done .............. ");
        }
    }
}

===================================================================

First a PrinterJob instance is obtained.
          PrinterJob pj = PrinterJob.getPrinterJob();

Then a panel will be popped to take a user input.  It's done by the code segment, 'pj.printDialog()', which returns true if the user chooses to print and false otherwise.


Then a JEditorPane instance is formed specifying the content type and an initial text.
         JEditorPane text = new JEditorPane("text/html", "text");
An alternative way to do the same is;
        JEditorPane text = new JEditorPane();
        text.setContentType("text/html");

The content should be set to the JEditorPane for printing.
Text can either be set like
       'text.setText("Return this page to Shyarmal.");'
or read from a file as done in the example
[ text.read(new BufferedReader(new InputStreamReader(new FileInputStream(new File("a.html")))), ""); ]

Then repaint method should be called on the JEditorPane for the changes to it be updated.

'pj.setPrintable(text.getPrintable(head, foot))' sets the JEditorPane for printing.
The print() method of PrinterJob, does the printing.


thanks,
Shyarmal.

Thursday, August 4, 2011

Printing example with Java EE

Following  is an approach to printing a document using a servlet. The example uses a template which is in html to generate a page (an invoice) and then prints it. Place holders of variable fields of the invoice are obtained via the user session and replaced appropriately. Since the clients should be getting a printout of the invoice, the printing has to be done through the browser (using a javascript).

===================================================================
package com.shyarmal.web.services;

import com.shyarmal.web.util.DateTimeUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class InvoicePrinter extends HttpServlet {

    private static final String TEMPLATE_NAME = "/invoice.tpl";
    
    private static final Logger LOGGER = Logger.getLogger(InvoicePrinter.class);
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        LOGGER.info("printing receipt ....");
        try {
            Map receiptDetails = (Map) req.getSession().getAttribute("recieptParameters");
            receiptDetails.put("date", DateTimeUtil.getDate());
            receiptDetails.put("time", DateTimeUtil.getTime());
            PrintWriter pw = resp.getWriter();
            pw.print(replaceTokens(readTemplate(), receiptDetails));
            pw.flush();
            pw.close();
        } catch (Exception e) {
            LOGGER.error("Printing failed .... ", e);
        } finally {
            LOGGER.info("quit printer task.... ");
        }
    }
    
    private String readTemplate() throws IOException {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(TEMPLATE_NAME)));
            StringBuffer sb = new StringBuffer();
            while(br.ready()) {
                sb.append(br.readLine());
            }
            
            return sb.toString();
        } finally {
            br.close();
        }
    }
    
    private String replaceTokens(String text, Map replacements) {
        Pattern pattern = Pattern.compile("\\[(.+?)\\]");
        Matcher matcher = pattern.matcher(text);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            String replacement = (String)replacements.get(matcher.group(1));
            if(replacement != null) {
                matcher.appendReplacement(sb, "");
                sb.append(replacement);
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

}
===================================================================

I have posted a sample template which will be used to generate the invoice below. The segments to be replaced are enclosed with square brackets. Replacement of tokens is done in the method replaceTokens(String, Map) method. The keys of the map should map the names of the placeholders which are given within square brackets. Actually the printing is done by onLoad='self.print()' call in the body tag of the template. All what the servlet does is creating the specific invoice for the user and displaying it.

===================================================================
<!DOCTYPE html PUBLIC
'-//W3C//DTD XHTML 1.0 Transitional//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml'> <head> <title>Untitled Document</title> <style type='text/css'> <!-- ----- css codes ------- --> </style> </head> <body style='font: Arial; color:#333333' onLoad='self.print()'> <br /><br /><br /> <table width='100' border='0' align='center' cellpadding='1' cellspacing='0' bgcolor='#A21D18'> <tr> <td bgcolor='#A21D18'>
<table width='455' border='0' align='left' cellpadding='0' cellspacing='0' bgcolor='#FFFFFF'> <tr> <td width='350' height='30' class='style2'> <div align='left' style='padding-left:30px;'>Date : [date] </div> </td> <td width='350' class='style2'> <div align='left' style='padding-left:30px;'>Time : [time] </div> </td> </tr> <tr> <td colspan='2' class='style2'>
<div align='left' style='padding-left:50px; padding-right:50px; padding-top:5px;'> <table width='100%' border='0' cellspacing='0' cellpadding='0'> <tr> <td width='48%'><u>Invoice</u></td> <td width='4%'>&nbsp;</td> <td width='48%'>&nbsp;</td> </tr> <tr> <td>ID/Passport No </td> <td align='center'>:</td> <td>[nic]</td> </tr> <tr> <td>Name</td> <td align='center'>:</td> <td>[first_name] &nbsp; [last_name]</td> </tr> <tr> <td>Billing Address</td> <td align='center'>:</td> <td>[address]</td> </tr> <tr> <td>Billing Country</td> <td align='center'>:</td> <td>Sri Lanka</td> </tr> <tr> <td>Amount </td> <td align='center'>:</td> <td>LKR [amount]</td> </tr> </table> </div></td> </tr> </table></td> </tr> </table> </body> </html>
===================================================================

The javascript code in the jsp will be opening a new window and loading the invoice for the particular customer. The dimensions of the window opened will be 800 x 600 and will be sending a request to the above servlet with the url 'shopping/pringInvoice'. ['shopping/pringInvoice' is mapped to the servlet in the web.xml file.]
===================================================================

<script type="text/javascript">
  function print() {
    window.open('/shopping/printInvoice','receipt','width=600,height=800');
  }
</script>
===================================================================

The servlet should be defined and mapped in the web.xml.
===================================================================
<servlet-mapping>
<servlet-name>printInvoice</servlet-name>
<url-pattern>/printInvoice</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>printInvoice</servlet-name>
<servlet-class>com.shyarmal.web.services.InvoicePrinter</servlet-class>
</servlet>
==================================================================

thanks,
Shyarmal.