java.awt.print.PrinterException: Paper's imageable height is too small - java

Im new to java and trying to print a pdf file using the following code but, I keep getting the above expetion. Can you help me soving it?
This is my code
private void printMergedFile(String printerName, String job, String fileName) throws IOException, PrinterException
{
PrintService[] service = PrinterJob.lookupPrintServices(); // list of printers
DocPrintJob docPrintJob = null;
PrinterJob pjob = PrinterJob.getPrinterJob();
PDDocument doc = PDDocument.load(fileName);
int count = service.length;
for (int i = 0; i < count; i++) {
if (service[i].getName().equalsIgnoreCase(printerName )) {
docPrintJob = service[i].createPrintJob();
i = count;
}
}
pjob.setPrintService(docPrintJob.getPrintService());
pjob.setJobName(job);
pjob.print();
doc.silentPrint(pjob);
}
Tx

Related

java pdfbox printerjob wrong size on label

I create with my application a PDF file which has exactly the dimensions of the label. When I print this file with Adobe Reader, the result is from the top. When I print it in Java, not everything is printed.
= Adobe, 2. pdfbox
public static PrintService choosePrinter(String printerName) {
PrintService[] service = PrinterJob.lookupPrintServices(); // list of printers
PrintService printService = null;
int count = service.length;
for (int i = 0; i < count; i++) {
if (service[i].getName().equalsIgnoreCase(printerName)) {
printService = service[i];
i = count;
}
}
return printService;
}
public static void printPDF(String fileName, PrinterSetting printerSetting) throws IOException, PrinterException {
PDDocument pdf = PDDocument.load(new File(fileName));
PrinterJob job = PrinterJob.getPrinterJob();
// define custom paper
Paper paper = new Paper();
paper.setSize( printerSetting.getPageHeight(), printerSetting.getPageWidth()); // 1/72 inch
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
// custom page format
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
pageFormat.setOrientation(PageFormat.LANDSCAPE);
// override the page format
Book book = new Book();
// append all pages
PDFPrintable pdfPrintable = new PDFPrintable(pdf, Scaling.SHRINK_TO_FIT);
book.append(pdfPrintable, pageFormat, pdf.getNumberOfPages());
job.setPageable(book);
PrintService printService = choosePrinter(printerSetting.getPrinterName());
if(printService != null)
job.setPrintService(printService);
job.print();
}

Java code not able to print long receipt in thermal printer

My java thermal printer code not able to print long receipt(more than A4 sheet size). Its work fine normally, but in case where there is too much items in cart then it generate half print. My code is under mentioned-
public PrintReceipt(Map<String,String> hm){
/*
product details code..
*/
try{
input = new FileInputStream("C:/printer.properties");
prop.load(input);
printerName=prop.getProperty("receiptPrinter");
System.out.println("Printer Name "+printerName);
}catch(Exception exception){
System.out.println("Properties file not found");
}
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null,null);
for (int i = 0; i < pservices.length; i++) {
if (pservices[i].getName().equalsIgnoreCase(printerName)) {
job = PrinterJob.getPrinterJob();
PageFormat pf = job.defaultPage();
double margin = 1.0D;
Paper paper = new Paper();
paper.setSize(216D, paper.getHeight());
paper.setImageableArea(margin, margin, paper.getWidth() - margin * 1.5D, paper.getHeight() - margin * 1.5D);
pf.setPaper(paper);
job.setCopies(1);
pf.setOrientation(1);
job.setPrintable(this, pf);
try
{
job.print();
}
catch(PrinterException ex)
{
System.out.println("Printing failed");
}
}
}
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if(pageIndex > 0)
return 1;
Graphics2D g2d = (Graphics2D)graphics;
double width = pageFormat.getImageableWidth();
double height = pageFormat.getImageableHeight();
g2d.translate((int) pageFormat.getImageableX(),(int) pageFormat.getImageableY());
Font font = new Font("Monospaced",Font.BOLD,8);
g2d.setFont(font);
try {
/*
* Draw Image*
*/
int x=50 ;
int y=10;
int imagewidth=100;
int imageheight=50;
BufferedImage read = ImageIO.read(new File("C:/hotel.png"));
g2d.drawImage(read,x,y,imagewidth,imageheight,null); //draw image
g2d.drawString("-- * Resturant * --", 20,y+60);
g2d.drawLine(10, y+70, 180, y+70); //draw line
} catch (IOException e) {
e.printStackTrace();
}
try{
/*Draw Header*/
/*
product details code..
*/
/*Footer*/
//end of the receipt
}
catch(Exception r){
r.printStackTrace();
}
return 0;
}
Please let me know how can i generate long receipt print by correcting my code or if you have any better solution to do this.
Right here:
Paper paper = new Paper();
paper.setSize(216D, paper.getHeight());
You are creating a new Paper object and not setting its height.
Here is a link to the documentation of this class.
When creating a Paper object, it is the application's responsibility to ensure that the paper size and the imageable area are compatible
You need to set the height of the paper by calling paper.setSize(width, height) or it will use its default size property.
The dimensions are supplied in 1/72nds of an inch.
So both width and height will need to be provided in this format as doubles
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
PrintService printService[] = PrintServiceLookup.lookupPrintServices(
flavor, pras);
PrintService service = findPrintService(printerName, printService);
PDDocument document = PDDocument.load(bytes);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(service);
job.setPageable(new PDFPageable(document));
job.print();
if (document != null) {
document.close();
}

Java File Iteration in For loop

I have few files saved in my local directory. One video file and one
xml file. Video file details will be stored in xml file.
We are moving videos from one system to another system. Before
uploading the video file and xml data from one system to another
system, need to check for the title of video in the other system and
upload only if the same title doesn't exist.
This is working fine. But uploading is happening 4 times instead of 2
times. Please help.
Here is the main code:
List<File> videoFiles = new ArrayList<File>();
List<File> xmlFiles = new ArrayList<File>();
File[] allVideos = checkVideos();
for(File file:allVideos ) {
if(file.getName().endsWith("flv")) {
videoFiles .add(file);
}
if(file.getName().endsWith("xml")) {
xmlFiles .add(file);
}
}
System.out.println(videoFiles.size());
System.out.println(xmlFiles.size());
processUpload(videoFiles ,xmlFiles);
Here are the methods:
private static void processUpload(List<File> videoFiles, List<File> xmlFiles) throws ParserConfigurationException, SAXException, IOException, ApiException {
NodeList nodes = null;
File video= null;
File xml = null;
String title = null;
String localFileTitle = null;
Media newMedia = null;
for(int i=0;i < videoFiles.size();i++) {
System.out.println("videoFiles.getName() ->"+videoFiles.get(i).getName());
video= videoFiles.get(i);
for(int j=0;j < xmlFiles.size();j++) {
xml = xmlFiles.get(j);
System.out.println("xmlFiles.getName() ->"+xmlFiles.get(i).getName());
nodes = parseXml(xml);
localFileTitle = processNodes(nodes);
title = checkTitles(localFileTitle);
newMedia = initiateUploadProcess(flv, title );
}
}
}
private static NodeList parseXml(File xmlFile) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
//System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("video");
return nList;
}
private static String processNodes(NodeList nodes) {
String fileTitle = null;
if(nodes.getLength() >= 1) {
for (int temp = 0; temp < nodes.getLength(); temp++) {
Node nNode = nodes.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
fileTitle = eElement.getElementsByTagName("title").item(0).getTextContent();
if(fileTitle != null) {
//System.out.println("Local File Title ------>"+fileTitle);
}
}
}
}
return fileTitle;
}
private static String checkTitles(String localTitle) throws ApiException {
String title = null;
MediaList mediaResponse = fetchVideos(caID);
if(mediaResponse.totalCount >= 1) {
for(MediaEntry media:mediaResponse.objects) {
if(!localTitle.equals(media.name)) {
System.out.println("Titles are not same. Need to return");
title = localTitle;
}
}
}
return title ;
}
private static MediaEntry initiateUploadProcess(File videoFile,
String localFileTitle) throws ApiException, ParserConfigurationException, SAXException, IOException {
UploadToken ktoken = null;
UploadMedia entry = null;
MediaEntry mediaEntry = null;
ktoken = generateToken();
if (ktoken != null) {
//System.out.println("ktoken.id ----------->" + ktoken.id);
if (ktoken.id != null) {
uploadToken(ktoken.id, flvFile);
entry = uploadMediaToChannel(categoryID, categoryName, localFileTitle);
if (entry.id != null) {
System.out.println("entry.id ------->" + entry.id);
mediaEntry = addMediaContent(ktoken.id, entry.id);
}
}
}
return mediaEntry;
}
Here is the output:
videoFiles.getName() ->22701846_91167469.flv
xmlFiles.getName() ->22701846_91167469.xml
Titles are not same. Need to return
Titles are not same. Need to return
video.id ------->0_50wh1m4p
xmlFiles.getName() ->22701846_91167469.xml
Titles are not same. Need to return
Titles are not same. Need to return
video.id ------->0_79v605ue
videoFiles.getName() ->22701846_91477939.flv
xmlFiles.getName() ->22701846_91477939.xml
Titles are not same. Need to return
Titles are not same. Need to return
video.id ------->0_0kihent1
xmlFiles.getName() ->22701846_91477939.xml
Titles are not same. Need to return
Titles are not same. Need to return
Titles are not same. Need to return
video.id ------->0_miogft0i
In pseudo-code, you have something like those two loops there:
for (i in 1,2)
for (j in 1, 2)
...
upload
And you are surprised that you have 4 (2 x 2) uploads?
Try something like:
for (i in 1,2)
... fetch video file info
... fetch xml file info
upload
instead!
Doing the nested for loops is not very efficient, but I think the problem is in your checkVideos() method (not listed in the question) and it is returning duplicate file objects.
Edit: the line where you print the xml file is using the "i" variable (from the outer loop)

How to find blank pages inside a PDF using PDFBox?

Here is the challenge I'm currently facing.
I have a lot of PDFs and I have to remove the blank pages inside them and display only the pages with content (text or images).
The problem is that those pdfs are scanned documents.
So the blank pages have some dirty left behind by the scanner.
I did some research and ended up with this code that checks for 99% of the page as white or light gray.
I needed the gray factor as the scanned documents sometimes are not pure white.
private static Boolean isBlank(PDPage pdfPage) throws IOException {
BufferedImage bufferedImage = pdfPage.convertToImage();
long count = 0;
int height = bufferedImage.getHeight();
int width = bufferedImage.getWidth();
Double areaFactor = (width * height) * 0.99;
for (int x = 0; x < width ; x++) {
for (int y = 0; y < height ; y++) {
Color c = new Color(bufferedImage.getRGB(x, y));
// verify light gray and white
if (c.getRed() == c.getGreen() && c.getRed() == c.getBlue()
&& c.getRed() >= 248) {
count++;
}
}
}
if (count >= areaFactor) {
return true;
}
return false;
}
#Shoyo's code works fine for PDFBox version < 2.0. For future readers, there's no much change but, just in case, here is the code for PDFBOX 2.0+ to make your life easier.
In your main (By main, I mean the place where you are loading your PDF into PDDocument) method:
try {
PDDocument document = PDDocument.load(new File("/home/codemantra/Downloads/tetml_ct_access/C.pdf"));
PDFRenderer renderedDoc = new PDFRenderer(document);
for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {
if(isBlank(renderedDoc.renderImage(pageNumber))) {
System.out.println("Blank Page Number : " + pageNumber + 1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
And isBlank method will just have BufferedImage passed in:
private static Boolean isBlank(BufferedImage pageImage) throws IOException {
BufferedImage bufferedImage = pageImage;
long count = 0;
int height = bufferedImage.getHeight();
int width = bufferedImage.getWidth();
Double areaFactor = (width * height) * 0.99;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color c = new Color(bufferedImage.getRGB(x, y));
if (c.getRed() == c.getGreen() && c.getRed() == c.getBlue() && c.getRed() >= 248) {
count++;
}
}
}
if (count >= areaFactor) {
return true;
}
return false;
}
All the credits goes to #Shoyo
Update:
Some PDFs have "This Page was Intentionally Left Blank" to which the above code considers as blank. If this is your requirement then feel free to use the above code. But, my requirement was only to filter out the pages that were completely blank (No any images present nor consisting of any fonts). So, I ended up using this code (Plus this code runs faster :P) :
public static void main(String[] args) {
try {
PDDocument document = PDDocument.load(new File("/home/codemantra/Downloads/CTP2040.pdf"));
PDPageTree allPages = document.getPages();
Integer pageNumber = 1;
for (PDPage page : allPages) {
Iterable<COSName> xObjects = page.getResources().getXObjectNames();
Iterable<COSName> fonts = page.getResources().getFontNames();
if(xObjects.spliterator().getExactSizeIfKnown() == 0 && fonts.spliterator().getExactSizeIfKnown() == 0) {
System.out.println(pageNumber);
}
pageNumber++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
This will return the page numbers of those pages which are completely blank.
Hope this helps someone! :)
#Pramesh Bajracharya, Your solution to find a blank page in a PDF document is intact!
If in case the requirement is to remove the blank pages the same code can be enhanced as below
List<Integer> blankPageList = new ArrayList<Integer>();
for( PDPage page : allPages )
{
Iterable<COSName> xObjects = page.getResources().getXObjectNames();
Iterable<COSName> fonts = page.getResources().getFontNames();
// condition to determine if the page is a blank page
if( xObjects.spliterator().getExactSizeIfKnown() == 0 && fonts.spliterator().getExactSizeIfKnown() == 0 )
{
pageRemovalList.add( pageNumber );
}
pageNumber++;
}
// remove the blank pages from the pdf document using the blank page numbers list
for( Integer i : blankPageList )
{
document.removePage( i );
}
http://www.rgagnon.com/javadetails/java-detect-and-remove-blank-page-in-pdf.html
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.io.RandomAccessSourceFactory;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
public class RemoveBlankPageFromPDF {
// value where we can consider that this is a blank image
// can be much higher or lower depending of what is considered as a blank page
public static final int BLANK_THRESHOLD = 160;
public static void removeBlankPdfPages(String source, String destination)
throws IOException, DocumentException
{
PdfReader r = null;
RandomAccessSourceFactory rasf = null;
RandomAccessFileOrArray raf = null;
Document document = null;
PdfCopy writer = null;
try {
r = new PdfReader(source);
// deprecated
// RandomAccessFileOrArray raf
// = new RandomAccessFileOrArray(pdfSourceFile);
// itext 5.4.1
rasf = new RandomAccessSourceFactory();
raf = new RandomAccessFileOrArray(rasf.createBestSource(source));
document = new Document(r.getPageSizeWithRotation(1));
writer = new PdfCopy(document, new FileOutputStream(destination));
document.open();
PdfImportedPage page = null;
for (int i=1; i<=r.getNumberOfPages(); i++) {
// first check, examine the resource dictionary for /Font or
// /XObject keys. If either are present -> not blank.
PdfDictionary pageDict = r.getPageN(i);
PdfDictionary resDict = (PdfDictionary) pageDict.get( PdfName.RESOURCES );
boolean noFontsOrImages = true;
if (resDict != null) {
noFontsOrImages = resDict.get( PdfName.FONT ) == null &&
resDict.get( PdfName.XOBJECT ) == null;
}
System.out.println(i + " noFontsOrImages " + noFontsOrImages);
if (!noFontsOrImages) {
byte bContent [] = r.getPageContent(i,raf);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
bs.write(bContent);
System.out.println
(i + bs.size() + " > BLANK_THRESHOLD " + (bs.size() > BLANK_THRESHOLD));
if (bs.size() > BLANK_THRESHOLD) {
page = writer.getImportedPage(r, i);
writer.addPage(page);
}
}
}
}
finally {
if (document != null) document.close();
if (writer != null) writer.close();
if (raf != null) raf.close();
if (r != null) r.close();
}
}
public static void main (String ... args) throws Exception {
removeBlankPdfPages
("C://temp//documentwithblank.pdf", "C://temp//documentwithnoblank.pdf");
}
}

Print text File to specific printer in java

I have a text file, and I need to print it to a specific network printer. I know the name of the printer.
Until now I have made a Printable class to print my file (ticket).
public class TicketPrintPage implements Printable {
private File ticket;
public TicketPrintPage(File f) {
ticket = f;
}
public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException {
int interline = 12;
Graphics2D g2 = (Graphics2D) g;
g2.setFont(new Font("CourierThai", Font.PLAIN, 10));
int x = (int) pf.getImageableX();
int y = (int) pf.getImageableY();
try {
FileReader fr = new FileReader(ticket);
BufferedReader br = new BufferedReader(fr);
String s;
while ((s = br.readLine()) != null) {
y += interline;
g2.drawString(s, x, y);
}
} catch (IOException e) {
throw new PrinterException("File to print does not exist (" + ticket.getAbsolutePath() +") !");
}
return Printable.PAGE_EXISTS;
}
}
I call this TicketPrintPage this way :
public void printTicketFile(File ticket, int orientation) throws PrinterException {
if (!ticket.exists()) {
throw new PrinterException("Ticket to print does not exist (" + ticket.getAbsolutePath() + ") !");
}
PrinterJob pjob = PrinterJob.getPrinterJob();
// get printer using PrintServiceLookup.lookupPrintServices(null, null) and looking at the name
pjob.setPrintService(getPrintService());
// job title
pjob.setJobName(ticket.getName());
// page fomat
PageFormat pf = pjob.defaultPage();
// landscape or portrait
pf.setOrientation(orientation);
// Paper properties
Paper a4Paper = new Paper();
double paperWidth = 8.26;
double paperHeight = 11.69;
double margin = 16;
a4Paper.setSize(paperWidth * 72.0, paperHeight * 72.0);
a4Paper.setImageableArea(
margin,
//0,
margin,
//0,
a4Paper.getWidth()- 2 * margin,
//a4Paper.getWidth(),
a4Paper.getHeight()- 2 * margin
//a4Paper.getHeight()
); // no margin = no scaling
pf.setPaper(a4Paper);
// Custom class that defines how to layout file text
TicketPrintPage pages = new TicketPrintPage(ticket);
// adding the page to a book
Book book = new Book();
book.append(pages, pf);
// Adding the book to a printjob
pjob.setPageable(book);
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
// No jobsheet (banner page, the page with user name, job name, date and whatnot)
pras.add(JobSheets.NONE);
// Printing
pjob.print(pras);
}
It works not so bad but :
- I doesn't work for more than one page of text (found some algorithms for that but well)
- I can't get to know when the printer is done printing, and if I try printing two or more tickets in a row the printer will return a Printer not ready message.
So the question again is : Isn't there a simple way to print a text file to a printer ?
JTextComponent#print should do the trick:
JTextPane jtp = new JTextPane();
jtp.setBackground(Color.white);
jtp.setText("text to print");
boolean show = true;
try {
jtp.print(null, null, show, null, null, show);
} catch (java.awt.print.PrinterException ex) {
ex.printStackTrace();
}
in this manner you can quickly print out even nice formatted text - just create a StyledDocument and attach it to JTextPane before printing.
I'm not sure if this solves your problem but I use the following to print a text file
FileInputStream textStream;
textStream = new FileInputStream(FILE_NAME);
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
Doc mydoc = new SimpleDoc(textStream, flavor, null);
PrintService[] services = PrintServiceLookup.lookupPrintServices(
flavor, aset);
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
if(services.length == 0) {
if(defaultService == null) {
//no printer found
} else {
//print using default
DocPrintJob job = defaultService.createPrintJob();
job.print(mydoc, aset);
}
} else {
//built in UI for printing you may not use this
PrintService service = ServiceUI.printDialog(null, 200, 200, services, defaultService, flavor, aset);
if (service != null)
{
DocPrintJob job = service.createPrintJob();
job.print(mydoc, aset);
}
}
You may not need the ServiceUI, but I think you could use PrintService[] services to get a list of printers available for printing. And using an input stream and the Doc class you can print a file to a printer.

Categories