Sending data to a printer in Java - java

The code below sends data to a printer however, while it reaches the printer queue it comes back with a Unable to convert PostScript file. I thought that this would be overcome by specifying the flavor but this is not the case
import javax.print.Doc;
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.PrintServiceAttribute;
import javax.print.attribute.standard.PrinterName;
public class New1 {
public static void main(String[] args) {
try {
String s = "Hello";
// byte[] by = s.getBytes();
DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN;
PrintService pservice = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = pservice.createPrintJob();
Doc doc = new SimpleDoc(s, flavor, null);
job.print(doc, null);
} catch (PrintException e) {
e.printStackTrace();
}
}
}

Using only JPS you will have problems with Mac.
My suggestion is use Java 2 Print API + Java Print Service.
Java 2 Print API is something like 1990 style. To avoid to create your code using Java 2 Print API you could use PDFBox http://pdfbox.apache.org as a framework.
With PDFBox you could create a PDF document (http://pdfbox.apache.org/1.8/cookbook/documentcreation.html) but instead of save, print it using that code:
PrinterJob printJob = PrinterJob.getPrinterJob();
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
printJob.setPrintService(service);
document.silentPrint(printJob);
It works fine in my Mac.

Related

Unable to perform silent print :java

Why this below code ask to choose printer everytime when i run ? I am trying to perform silent print at once whenever i run this below code.
Is there any way how to set printer only once?
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import org.apache.pdfbox.pdmodel.PDDocument;
public class PdfBoxPrint {
public static PrintService choosePrinter() {
PrinterJob printJob = PrinterJob.getPrinterJob();
if(printJob.printDialog()) {
return printJob.getPrintService();
}
else {
return null;
}
}
public static void main(String[] args) throws IOException, PrinterException {
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
PrintRequestAttributeSet patts = new HashPrintRequestAttributeSet();
patts.add(Sides.DUPLEX);
PrintService[] ps = PrintServiceLookup.lookupPrintServices(flavor, patts);
if (ps.length == 0) {
throw new IllegalStateException("No Printer found");
}
System.out.println("Available printers: " + Arrays.asList(ps));//Prints default: "Available printers: [Win32 Printer : Fax]"
// Locate the default print service for this environment.
PrintService myService = PrintServiceLookup.lookupDefaultPrintService();
// Create and return a PrintJob capable of handling data from
// any of the supported document flavors.
System.out.println("Default Printer: "+myService.getName());
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(choosePrinter());
URL myURL = new URL("[SOME LINK TO A PDF]");
PDDocument pdf=PDDocument.load(myURL);
pdf.silentPrint(job);
}
}
You grab the default printer with
PrintService myService = PrintServiceLookup.lookupDefaultPrintService();
But then you toss it away with
job.setPrintService(choosePrinter());
If you want the default printer, use it. If not, prompt. If you only want to prompt the first time, well, then you have a data persistence problem and you should be storing your preferences somewhere and then re-loading them at a later time. When you load them, use your PrintServiceLookup.lookupPrintServices to match, set print service, etc.

How to setup zxing library on Windows 8 machine?

I have images of codes that I want to decode. How can I use zxing so that I specify the image location and get the decoded text back, and in case the decoding fails (it will for some images, that's the project), it gives me an error.
How can I setup zxing on my Windows machine? I downloaded the jar file, but I don't know where to start. I understand I'll have to create a code to read the image and supply it to the library reader method, but a guide how to do that would be very helpful.
I was able to do it. Downloaded the source and added the following code. Bit rustic, but gets the work done.
import com.google.zxing.NotFoundException;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Reader;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.Result;
import com.google.zxing.LuminanceSource;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.*;
import com.google.zxing.qrcode.QRCodeReader;
class qr
{
public static void main(String args[])
{
Reader xReader = new QRCodeReader();
BufferedImage dest = null;
try
{
dest = ImageIO.read(new File(args[0]));
}
catch(IOException e)
{
System.out.println("Cannot load input image");
}
LuminanceSource source = new BufferedImageLuminanceSource(dest);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Vector<BarcodeFormat> barcodeFormats = new Vector<BarcodeFormat>();
barcodeFormats.add(BarcodeFormat.QR_CODE);
HashMap<DecodeHintType, Object> decodeHints = new HashMap<DecodeHintType, Object>(3);
decodeHints.put(DecodeHintType.POSSIBLE_FORMATS, barcodeFormats);
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = null;
try
{
result = xReader.decode(bitmap, decodeHints);
System.out.println("Code Decoded");
String text = result.getText();
System.out.println(text);
}
catch(NotFoundException e)
{
System.out.println("Decoding Failed");
}
catch(ChecksumException e)
{
System.out.println("Checksum error");
}
catch(FormatException e)
{
System.out.println("Wrong format");
}
}
}
The project includes a class called CommandLineRunner which you can simply call from the command line. You can also look at its source to see how it works and reuse it.
There is nothing to install or set up. It's a library. Typically you don't download the jar but declare it as a dependency in your Maven-based project.
If you just want to send an image to decode, use http://zxing.org/w/decode.jspx

Can't find a Print Service using java in Windows

I am trying to locate a print service that can handle a job, i am using the PrintService API in Java.
This is my code:
private PrintService[] services = null;
services = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.PDF, null);
System.out.println("We found : " + services.length + " service(s)");
The output was always:
We found : 0 service(s)
I don't know why it can't find a service although I have a printer installed in my computer! noted that:
The printer work very well
I used the same code before when i had Linux OS, it worked. Now i am using Windows..
There was no PrintService found corresponding to the specified DocFlavor: 'PDF'
Because when i tried to find out which are the DocFlavor supported by my printer:
PrintService[] prnSvc = PrintServiceLookup.lookupPrintServices(null, null);
DocFlavor[] docFalvor = prnSvc[0].getSupportedDocFlavors();
for (int i = 0; i < docFalvor.length; i++) {
System.out.println(docFalvor[i].getMimeType());
}
I got just:
image/gif
image/gif
image/gif
image/jpeg
image/jpeg
image/jpeg
image/png
image/png
image/png
application/x-java-jvm-local-objectref
application/x-java-jvm-local-objectref
application/octet-stream
application/octet-stream
application/octet-stream
Similar posts: Printer services Not found? and Java Print program with Specfications issues?
It seems like there is a problem with the PDF capability under Windows. I ran into the same problem and haven't found a solution yet.
Other people have found a workaround, but this seems to be illegal by now (see https://community.oracle.com/thread/2046162).
EDIT
I worked around this problem by converting the PDF to a PNG image.
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static javax.imageio.ImageIO.write;
import static org.apache.pdfbox.pdmodel.PDDocument.load;
public class PdfToImageConverter {
public static String GIF = "gif";
public static String JPG = "jpg";
public static String PNG = "png";
public static byte[] convertPdfTo(final String imageType, final byte[] pdfContent) throws IOException {
final PDDocument document = load(new ByteArrayInputStream(pdfContent));
final List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
final PDPage pdPage = allPages.get(0);
final BufferedImage image = pdPage.convertToImage(TYPE_INT_RGB, 300);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
write(image, "png", outputStream);
outputStream.flush();
final byte[] imageInByte = outputStream.toByteArray();
outputStream.close();
return imageInByte;
}
}
I added MediaSizeName.ISO_A4 as PrintRequestAttribute to the PrintJob, this solution works for me.

Printing landscape documents with Java on duplex mode

I've a JasperReports report to be printed on landscape mode on a duplex printer. On this I've to support PCL5 and PCL6 printing drivers.
Searching on the internet, I discovered the following code snippet to do this job:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Sides;
public class PrintingTest {
public static void main(String[] args) {
try {
//This are for configuration purpose
String orientation = "LANDSCAPE";
String duplexMode = "LONG_EDGE";
int pageOrientation = 0;
PrintRequestAttributeSet atr = new HashPrintRequestAttributeSet();
if ("Landscape".equals(orientation)) {
atr.add(OrientationRequested.LANDSCAPE);
pageOrientation = PageFormat.LANDSCAPE;
} else if ("Reverse_Landscape".equals(orientation)) {
atr.add(OrientationRequested.REVERSE_LANDSCAPE);
pageOrientation = PageFormat.REVERSE_LANDSCAPE;
} else {
atr.add(OrientationRequested.PORTRAIT);
pageOrientation = PageFormat.PORTRAIT;
}
if ("LONG_EDGE".equals(duplexMode)) {
atr.add(Sides.TWO_SIDED_LONG_EDGE);
} else {
atr.add(Sides.TWO_SIDED_SHORT_EDGE);
}
//Printing to the default printer
PrintService printer = javax.print.PrintServiceLookup
.lookupDefaultPrintService();
//Creating the printing job
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintService(printer);
Book book = new Book();
PageFormat pageFormat = printJob.defaultPage();
pageFormat.setOrientation(pageOrientation);
// Appending a exampledocument to the book
book.append(new ExampleDocument(), pageFormat);
// Appending another exampledocument to the book
book.append(new ExampleDocument(), pageFormat);
// Setting the Pageable to the printjob
printJob.setPageable(book);
try {
// Here a could show the print dialog
// printJob.printDialog(atr);
// Here I pass the previous defined attributes
printJob.print(atr);
} catch (Exception PrintException) {
PrintException.printStackTrace();
}
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
public static final int MARGIN_SIZE = 72;
private static class ExampleDocument implements Printable {
public int print(Graphics g, PageFormat pageFormat, int page) {
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pageFormat.getImageableX(),
pageFormat.getImageableY());
// Only on the first two documents...
if (page <= 1) {
// Prints using one inch margin
g2d.drawString("Printing page " + page + " - duplex...",
MARGIN_SIZE, MARGIN_SIZE);
return (PAGE_EXISTS);
}
return (NO_SUCH_PAGE);
}
}
}
This works fine on PCL6, but, when tested on PCL5, I noticed that LONG_EDGE and SHORT_EDGE rules are simple ignored. And that in both cases the job is sent as LONG_EDGE. This would not be a problem, except that Java AWT printing API resolves landscape printing by turning all pages 90ยบ anti-clockwise causing the impression that it was printed on SHORT_EDGE mode.
Obs: I was able to print correctly with both configuration, SHORT_EDGE and LONG_EDGE, in portrait and in landscape, by using the SWT API. But I'm not able to convert the jasper printing request in a SWT compatible printing request.
My question is: has anybody ever confronted this situation? Which solution was given to it?
From my observation I've found these possible solutions:
Instead of letting the AWT turn the page and send a portrait print request, force it to send it as a landscape printing request;
Find a way to, when the page is in landscape mode, invert LONG_EDGE and SHORT_EDGE commands. Observe that for this one I would be obligated to correct the problem in which both are treated as LONG_EDGE requests.
Convert the JasperReports to use SWT printing API.
Not sure it helps but I had this issue 6 years ago and the only solution was to use the printer's (Xerox) capability to receive the printing directives through an .xpf file. Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xpif SYSTEM "xpif-v02012.dtd">
<xpif cpss-version="2.01" version="1.0" xml:lang="en">
<xpif-operation-attributes>
<job-name syntax="name" xml:lang="en" xml:space="preserve">job name</job-name>
<requesting-user-name syntax="name" xml:space="preserve">domain user</requesting-user-name>
</xpif-operation-attributes>
<job-template-attributes>
<copies syntax="integer">1</copies>
<finishings syntax="1setOf">
<value syntax="enum">3</value>
</finishings>
<job-recipient-name syntax="name" xml:lang="en-US" xml:space="preserve">domain user</job-recipient-name>
<job-save-disposition syntax="collection">
<save-disposition syntax="keyword">none</save-disposition>
</job-save-disposition>
<media-col syntax="collection">
<media-type syntax="keyword">stationery</media-type>
<media-hole-count syntax="integer">0</media-hole-count>
<media-color syntax="keyword">blue</media-color>
<media-size syntax="collection">
<x-dimension syntax="integer">21000</x-dimension>
<y-dimension syntax="integer">29700</y-dimension>
</media-size>
</media-col>
<orientation-requested syntax="enum">3</orientation-requested>
<sheet-collate syntax="keyword">collated</sheet-collate>
<sides syntax="keyword">one-sided</sides>
<x-side1-image-shift syntax="integer">0</x-side1-image-shift>
<y-side1-image-shift syntax="integer">0</y-side1-image-shift>
</job-template-attributes>
</xpif>
which was sent to the printer along with the file needed to be printed.

Java Applet PDF printing

I am trying to build a java applet which prints a PDF file and sends it to a label printer rather than the default. I explored desktop.print but couldn't work out how to specify the printer.
This is the code I have, i've tried to look for solutions but have ended stuck. I have signed the applet and the error it gives me it just says application error 0
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.print.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
public class printPDF extends JApplet {
public void init(){
String uri = System.getProperty("user.home") + "\\jobbase\\print.pdf";
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new PrinterName("label", null));
aset.add(new Copies(1));
PrintService[] pservices =
PrintServiceLookup.lookupPrintServices(flavor, aset);
if (pservices.length > 0) {
DocPrintJob printJob = pservices[0].createPrintJob();
try{
FileInputStream fis = new FileInputStream(uri);
Doc doc = new SimpleDoc(fis, flavor, null);
try {
printJob.print(doc, aset);
} catch (PrintException e) {
System.err.println(e);
}
} catch(IOException ioe){
ioe.printStackTrace(System.out);
}
} else {
System.err.println("No suitable printers");
}
}
}
You can't just send the PDF to the printer unless you know it can understand it. Most of the time you need to rasterize it on the client. I write a blog article explaining the options at http://www.jpedal.org/PDFblog/2010/01/printing-pdf-files-from-java/
If you know the name of the printer you can achieve this. In one client I needed silent printing: if a printer named appprinter was present, I used it, if not I tried with the default. This worked out fine.
For printing I use ICEPDF.
Kate: thanks for the suggestion, honestly IcePDF is pretty straight forward, this example is included in the source code that you can download from the link above. In order to obtain the PrinterService (aka printer) needed you can delete all the user input requested by keyboard and just use the one with the name you want.
So, in version 5.0.5: [install-folder]/examples/printservices/PrintService.java
delete user selection of printservice: lines 106 to 155
add instead:
PrintService selectedService=null;
for (int j=0;j<services.length;j++) {
if ("myprintername".equalsIgnoreCase(services[j].getName())) {
selectedService=aux[j];
}
}
Hope now it is more useful.
Best regards.

Categories