giovedì 12 luglio 2012

Stampa in Java

 Una possibile soluzione, adatta a un pò tutte le stampanti (anche di rete!).

 Nota: La JTextArea è utilizzata per ottenere un Printable...forse è possibile ottenerlo in maniera più pulita e corretta.


import java.awt.Font;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
import javax.swing.JTextArea;

public class Printer {


    /**
     * Restituisce le stampanti driver disponibili al momento sul client.
     */
    public static PrintService[] getAvailableSystemPrinters() {
        return PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
    }

    /**
     * @return Restituisce il {@link PrintService} di nome dato se presente,
     * {@literal null} altrinmenti.
     * @throws NullPointerException se l'argomento é {@literal null}.
     */
    public static PrintService getPrinterByName(String name) {
        if (name == null)
            throw new NullPointerException("name");
        PrintService[] printServices = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        for (PrintService ps : printServices) {
            if (name.equals(ps.getName()))
                return ps;
        }
        return null;
    }
    /**
     * @param args
     * @throws IOException
     * @throws FileNotFoundException
     */
    public static void main(String[] args) throws IOException  {

        //InputStream is = Printer.class.getResourceAsStream("content.txt");
        InputStream is = new FileInputStream("C:\\content_largo.txt");
        //Lista stampanti installate
        System.out.println("Stampanti installate:");
        for (PrintService service : getAvailableSystemPrinters()) {
            System.out.println(" - " + service.getName());
        }

        if (args.length > 0) {

            PrintService defaultPrintService = getPrinterByName(args[0]);
            DocPrintJob printerJob = defaultPrintService.createPrintJob();
            SimpleDoc simpleDoc = null;
            try {
                JTextArea textArea = new JTextArea(convertStreamToString(is));
                textArea.setFont(new Font("courier New", Font.PLAIN, 8));
                PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
                aset.add(MediaSizeName.ISO_A4);
                aset.add(OrientationRequested.PORTRAIT);
                simpleDoc = new SimpleDoc(textArea.getPrintable(null, null), new DocFlavor("application/x-java-jvm-local-objectref", "java.awt.print.Printable"), null);
                printerJob.print(simpleDoc, aset);
            } catch (PrintException ex) {
                ex.printStackTrace();
            }
        }
        else {
            System.err.println("Bisogna indicare una stampante!");
        }
    }

    private static String convertStreamToString(InputStream is) throws IOException {
        /*
         * To convert the InputStream to String we use the
         * Reader.read(char[] buffer) method. We iterate until the
         * Reader return -1 which means there's no more data to
         * read. We use the StringWriter class to produce the string.
         */
        if (is != null) {
            Writer writer = new StringWriter();

            char[] buffer = new char[1024];
            try {
                Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); //anche IBM-850
                int n;
                while ((n = reader.read(buffer)) != -1) {
                    writer.write(buffer, 0, n);
                }
            } finally {
                is.close();
            }
            return writer.toString();
        } else {      
            return "";
        }
    }
}