/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.jpedal.org
* (C) Copyright 1997-2008, IDRsolutions and Contributors.
*
* This file is part of JPedal
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* SilentPrint.java
* ---------------
*/
package org.jpedal.examples.printing;
import java.awt.print.*;
import java.io.File;
import java.lang.reflect.Array;
import java.util.Hashtable;
import javax.print.*;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
import org.jpedal.PdfDecoder;
import org.jpedal.examples.simpleviewer.paper.PaperSizes;
import org.jpedal.exception.PdfException;
import org.jpedal.fonts.FontMappings;
import org.jpedal.objects.PrinterOptions;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.PdfBook;
import org.jpedal.utils.PdfPageFormat;
/**
* This example prints a pdf file or directory of files using JPS
*/
public class SilentPrint {
String printerName;
/** flag to output information for debugging the code */
private static boolean debugCode = false;
/** correct separator for OS */
private final String separator = System.getProperty("file.separator");
/** the decoder object which decodes the pdf and returns a data object */
private PdfDecoder pdfDecoder = null;
/** used to enable printing a page at a spec index */
public static boolean customSetting = false;
/** number of page to be printed */
public static int pageMark = 1;
/** needs to be global for the printer selection to work */
public static DocPrintJob printJob = null;
/**
* So it can be used for testing without any bigger changes in the actual
* code
*/
public SilentPrint() {
}
/**
* example method to open a file and print the pages
*/
public SilentPrint(String file_name, String printerName) {
this.printerName=printerName;
/**
* if file name ends pdf, do the file otherwise do every pdf file in the
* directory. We already know file or directory exists so no need to
* check that, but we do need to check its a directory
*/
if (file_name.toLowerCase().endsWith(".pdf")) {
decodeAndPrintFile(file_name);
}
else {
/**
* get list of files and check directory
*/
String[] files = null;
File inputFiles = null;
/** make sure name ends with a deliminator for correct path later */
if (!file_name.endsWith(separator))
file_name = file_name + separator;
try {
inputFiles = new File(file_name);
if (!inputFiles.isDirectory()) {
System.err.println(file_name + " is not a directory. Exiting program");
} else
files = inputFiles.list();
}
catch (Exception ee) {
LogWriter.writeLog("Exception trying to access file " + ee.getMessage());
}
/** now work through all pdf files */
long fileCount = files.length;
for (int i = 0; i < fileCount; i++) {
if (files[i].toLowerCase().endsWith(".pdf")) {
logMessage(file_name + files[i]);
decodeAndPrintFile(file_name + files[i]);
// reset printer in case of lots of pages (cannot be reused)
try {
validatePrinter(printerName);
}
catch (PrinterException e) {
e.printStackTrace(); // To change body of catch statement use File | Settings | File Templates.
}
}
}
}
}
/**
* routine to decode a file and print it
*/
private void decodeAndPrintFile(String file_name) {
/**
* open the file and get page count
*/
try {
logMessage("Opening file :" + file_name + " to print.");
pdfDecoder = new PdfDecoder(true);
// decode_pdf.setExtractionMode(0, 72,1);
pdfDecoder.openPdfFile(file_name);
} catch (Exception e) {
reportError("Exception " + e + " in pdf code");
}
/**
* code to handle passwords - some PDFs have an empty password set
*/
if (pdfDecoder.isEncrypted() && !pdfDecoder.isFileViewable()) {
String password = null; // set your password here
try {
/** try and reopen with new password */
if (password == null)
pdfDecoder.setEncryptionPassword(password);
else
pdfDecoder.setEncryptionPassword("");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* print if allowed and values found
*/
if (pdfDecoder.isEncrypted() && !pdfDecoder.isFileViewable()) {
logMessage("Encrypted settings");
} else {
// mappings for non-embedded fonts to use
FontMappings.setFontReplacements();
printPages();
}
/** close the pdf file */
pdfDecoder.closePdfFile();
}
/**
* PRINTING CODE EXAMPLE. If you put this into a thread you will need to synchronize
* and ensure terminated if program exits.
*
* Uses pageable interface so does not work under 1.3
*/
private void printPages()
{
//Create set of attributes
PrintRequestAttributeSet attributes = getPrintRequestAttributeSet();
/**
* workaround to improve performance on PCL printing by printing
* using drawString or Java's glyph if font available in Java
*/
// decode_pdf.setTextPrint(PdfDecoder.NOTEXTPRINT); //normal mode - only needed to reset
// decode_pdf.setTextPrint(PdfDecoder.STANDARDTEXTSTRINGPRINT); //print all standard fonts with Java regardless of if embedded
// decode_pdf.setTextPrint(PdfDecoder.TEXTGLYPHPRINT); //intermediate mode - let Java create Glyphs if font matches
// decode_pdf.setTextPrint(PdfDecoder.TEXTSTRINGPRINT); //try and get Java to do all the work
//Automatically rotate and center the Pdf pages for best fit. Default is true.
pdfDecoder.setPrintAutoRotateAndCenter(true);
//Pdf page scaling options
// pdfDecoder.setPrintPageScalingMode(PrinterOptions.PAGE_SCALING_FIT_TO_PRINTER_MARGINS);
// pdfDecoder.setPrintPageScalingMode(PrinterOptions.PAGE_SCALING_NONE);
pdfDecoder.setPrintPageScalingMode(PrinterOptions.PAGE_SCALING_REDUCE_TO_PRINTER_MARGINS);
PdfBook pdfBook = new PdfBook(pdfDecoder, printJob.getPrintService(), attributes);
pdfBook.setChooseSourceByPdfPageSize(false);
SimpleDoc doc = new SimpleDoc(pdfBook, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
// used to track print activity
printJob.addPrintJobListener(new PDFPrintJobListener());
try {
printJob.print(doc, attributes);
}
catch (Exception e) {
LogWriter.writeLog("Exception " + e + " printing");
}
// any errors reported in JPedal
if (pdfDecoder.getPageFailureMessage().length() > 0)
System.out.println("Errors reported from JPedal=" + pdfDecoder.getPageFailureMessage());
}
/**
* This example method sets up a few attributes for a PrintService.
*
* See http://download.oracle.com/javase/1.4.2/docs/api/javax/print/attribute/PrintRequestAttribute.html
* http://download.oracle.com/javase/tutorial/2d/printing/services.html and
* http://download.oracle.com/javase/7/docs/technotes/guides/jps/spec/attributes.fm.html
* for further information regarding attributes.
*/
private PrintRequestAttributeSet getPrintRequestAttributeSet()
{
PrintRequestAttributeSet attributeSet = new HashPrintRequestAttributeSet();
// Name the print job
String[] jobString = pdfDecoder.getFileName().split("/");
JobName jobName = new JobName(jobString[jobString.length-1], null);
if(validateAttribute(jobName, attributeSet)) {
attributeSet.add(jobName);
}
//Print multiple copies
if(pageMark > 1) {
Copies copies = new Copies(pageMark);
SheetCollate collate = SheetCollate.COLLATED;
if(validateAttribute(copies, attributeSet) && validateAttribute(collate, attributeSet)) {
attributeSet.add(copies);
attributeSet.add(collate);
}
}
//Print out a page range
PageRanges range = new PageRanges("1-10");
if(validateAttribute(range, attributeSet)) {
attributeSet.add(range);
}
// Black and white print
// if(validateAttribute(Chromaticity.MONOCHROME, attributeSet)) {
// attributeSet.add(Chromaticity.MONOCHROME);
// }
// Draft print quality
// if(validateAttribute(PrintQuality.DRAFT, attributeSet)) {
// attributeSet.add(PrintQuality.DRAFT);
// }
return attributeSet;
}
/**
* @return true if the attribute is supported on the current PrintService
*/
private static boolean validateAttribute(Attribute att, PrintRequestAttributeSet attributeSet)
{
return printJob.getPrintService().isAttributeValueSupported(att, DocFlavor.SERVICE_FORMATTED.PAGEABLE, attributeSet);
}
/**
* Checks that the desired PrintService exists.
*
* @param newPrinter The name of the PrintService
* @return true if PrintService is available
* @throws PrinterException
*/
private static boolean validatePrinter(String newPrinter) throws PrinterException {
boolean matchFound = false;
PrintService[] service = PrinterJob.lookupPrintServices(); // list of printers
int count = service.length;
for (int i = 0; i < count; i++) {
if (service[i].getName().indexOf(newPrinter) != -1) {
printJob = service[i].createPrintJob();
i = count;
matchFound = true;
}
}
if (!matchFound) {
String list = "";
for (int i = 0; i < count; i++)
list = list + '\"' + service[i].getName() + "\",";
reportError("Printer " + newPrinter + " not supported. Options=" + list);
}
return matchFound;
}
/** single routine to log activity for easy debugging */
private static void logMessage(String message) {
// change to suit your needs
if (debugCode) {
System.out.println(message);
LogWriter.writeLog(message);
}
}
/** single routine so error handling can be easily setup */
private static void reportError(String message) {
// change to suit your needs
System.err.println(message);
LogWriter.writeLog(message);
}
/**
* main routine which checks for any files passed and runs the demo
*/
public static void main(String[] args) {
logMessage("Simple demo to print pages");
// check user has passed us a filename and use default if none
if (args.length != 2) {
System.out.println("Printing needs 2 parameters");
System.out.println("Parameter 1 - File name or directory (put in quotes if it contains spaces");
System.out.println("Parameter 2- a printer name");
System.out.println("---Available printers are---");
try {
PrintService[] service = PrinterJob.lookupPrintServices(); // list of printers
int count = service.length;
for (int i = 0; i < count; i++)
System.out.println("\"" + service[i].getName() + "\"");
}
catch (Exception e) {
e.printStackTrace(); // To change body of catch statement use File | Settings | File Templates.
}
}
else {
String file_name = args[0];
String printerName = args[1];
logMessage("File :" + file_name);
logMessage("Printer :" + printerName);
boolean validPrinter = false;
// check printer exists
try {
validPrinter = validatePrinter(printerName);
}
catch (PrinterException e) {
e.printStackTrace(); // To change body of catch statement use File | Settings | File Templates.
}
// check file exists
File pdf_file = new File(file_name);
// if file exists, open and get number of pages
if (pdf_file.exists() == false) {
logMessage("File " + file_name + " not found");
}
else if (!validPrinter) {
logMessage("Printer " + printerName + " not found");
}
else {
new SilentPrint(file_name,printerName);
}
}
}
/**
* listener code - just an example
*/
private static class PDFPrintJobListener implements PrintJobListener {
static final private boolean showMessages = false;
public void printDataTransferCompleted(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printDataTransferCompleted=" + printJobEvent.toString());
}
public void printJobCompleted(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printJobCompleted=" + printJobEvent.toString());
}
public void printJobFailed(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printJobEvent=" + printJobEvent.toString());
}
public void printJobCanceled(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printJobFailed=" + printJobEvent.toString());
}
public void printJobNoMoreEvents(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printJobNoMoreEvents=" + printJobEvent.toString());
}
public void printJobRequiresAttention(PrintJobEvent printJobEvent) {
if (showMessages)
System.out.println("printJobRequiresAttention=" + printJobEvent.toString());
}
}
}
|