I need to print a HTML File from my Java Application.
I have tried several methods.
Two of them are working, but not as expected.
Method 1:
Problem: The Print is cut of after three-quarter of the sheet.
try {
PrinterJob printJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = new PageFormat();
pageFormat.setOrientation(PageFormat.LANDSCAPE);
Paper paper = new Paper(); // Set to A4 size.
paper.setSize(594.936, 841.536); // Set the margins.
paper.setImageableArea(0, 0, 594.936, 841.536);
pageFormat.setPaper(paper);
XHTMLPanel panel = new XHTMLPanel();
panel.setDocument(new File("./documents/" + "Personalstamm"
+ ".html"));
printJob.setPrintable(new XHTMLPrintable(panel), pageFormat);
if (printJob.printDialog()) {
printJob.print();
}
} catch (Exception x) {
x.printStackTrace();
}
Method 2:
Problem: The printout is without the Stylesheet set in the HTML file.
PageFormat pageFormat = new PageFormat();
Paper a4paper = new Paper();
double paperWidth = 8.26;
double paperHeight = 11.69;
a4paper.setSize(paperWidth * 72.0, paperHeight * 72.0);
/*
* set the margins respectively the imageable area
*/
double leftMargin = 0.78; /* should be about 2cm */
double rightMargin = 0.78;
double topMargin = 0.78;
double bottomMargin = 0.78;
a4paper.setImageableArea(leftMargin * 72.0, topMargin * 72.0,
(paperWidth - leftMargin - rightMargin) * 72.0, (paperHeight
- topMargin - bottomMargin) * 72.0);
pageFormat.setPaper(a4paper);
pageFormat.setOrientation(PageFormat.LANDSCAPE);
DocumentRenderer documentRenderer = new DocumentRenderer(pageFormat,
"Report");
try {
FileInputStream stringReader = new FileInputStream(new File(
"./documents/" + "Personalstamm" + ".html"));
HTMLEditorKit htmlKit = new HTMLEditorKit();
HTMLDocument htmlDoc = (HTMLDocument) htmlKit
.createDefaultDocument();
htmlKit.read(stringReader, htmlDoc, 0);
documentRenderer.print(htmlDoc);
} catch (Exception x) {
x.printStackTrace();
}
Does anybody have an idea how to solve the problem in one of these methods?
Or do anybody have a better way to print a file from Java?
You can't print your HTML with CSS. The best shot that you got is to use PDFs, that's what they are for. Create a PDF from the HTML using Java and print it
Now i am using Apache PDFBox - A Java PDF Library and it's nearly what i was looking for.
My Code:
public void printFile(String fileName) {
//Convert to PDF
try {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(new File("./documents/html/"+fileName+".html"));
renderer.layout();
String fileNameWithPath = "./documents/pdf/"+fileName+".pdf";
FileOutputStream fos = new FileOutputStream(fileNameWithPath);
renderer.createPDF(fos);
fos.close();
} catch (Exception x) {
x.printStackTrace();
}
//Print with Dialog
try {
PrinterJob printJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = new PageFormat();
pageFormat.setOrientation(PageFormat.LANDSCAPE);
Paper paper = new Paper();
paper.setSize(595, 842);
paper.setImageableArea(0, 0, 595, 842);
pageFormat.setPaper(paper);
PDDocument doc = PDDocument.load(new File("./documents/pdf/"+fileName+".pdf"));
printJob.setPrintable(new PDPageable(doc), pageFormat);
if (printJob.printDialog()) {
printJob.print();
}
doc.close();
} catch (Exception x) {
x.printStackTrace();
}
}
Using Jasper Reports might solve the problem.
Related
I have an PDF what i want to print labels with PrinterJob. The problem is that the result is moved about 90 degrees, the printer is an Bixolon SLP-DX223. In the driversettings i have changed the label size in the main and default settings but there is no change on the print. If i print the pdf with the Acrobat Reader and the same settings the result ist perfekt but not with the PrinterJob print.
try {
PDDocument document = PDDocument.load(new File(file));
PrintService myPrintService = findPrintService(printer);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document, Orientation.PORTRAIT));
job.setPrintService(myPrintService);
job.setJobName(jobname);
job.setCopies(copies);
job.print();
document.close();
}
catch (PrinterException | IOException e) {
e.printStackTrace();
}
Thanks for help
the answer from #GilbertLeBlanc brings me to the result, the size of the paper was not definied, so i have use the following code:
double labelWidth = 50.8; //width in mm
double labelHeigth = 25.4; //height in mm
labelWidth = labelWidth / 0.353; //calculate size
labelHeight = labelHeight / 0.353; //calculate size
Paper paper = new Paper();
paper.setSize(labelWidth, labelHeight);
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
Book book = new Book();
book.append(new PDFPrintable(document), pageFormat, document.getNumberOfPages());
job.setPageable(book); //job is the printerjob
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();
}
I have a Problem, My code which converts a PDF to Printable Format that can be printed locks my pdf file.
My Code:
public class PDFPrinter {
public PDFPrinter(File file) {
try {
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
fis.close();
fc.close();
PDFFile pdfFile = new PDFFile(bb); // Create PDF Print Page
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
Paper a4paper = new Paper();
double paperWidth = 8.26;
double paperHeight = 11.69;
a4paper.setSize(paperWidth * 72.0, paperHeight * 72.0);
/*
* set the margins respectively the imageable area
*/
double leftMargin = 0.3;
double rightMargin = 0.3;
double topMargin = 0.5;
double bottomMargin = 0.5;
a4paper.setImageableArea(leftMargin * 72.0, topMargin * 72.0,
(paperWidth - leftMargin - rightMargin) * 72.0,
(paperHeight - topMargin - bottomMargin) * 72.0);
pf.setPaper(a4paper);
pjob.setJobName(file.getName());
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
// Send print job to default printer
if (pjob.printDialog()) {
pjob.print();
}
} catch (IOException e) {
e.printStackTrace();
} catch (PrinterException e) {
JOptionPane.showMessageDialog(null, "Printing Error: "
+ e.getMessage(), "Print Aborted",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
class PDFPrintPage implements Printable {
private PDFFile file;
PDFPrintPage(PDFFile file) {
this.file = file;
}
public int print(Graphics g, PageFormat format, int index)
throws PrinterException {
int pagenum = index + 1;
// don't bother if the page number is out of range.
if ((pagenum >= 1) && (pagenum <= file.getNumPages())) {
// fit the PDFPage into the printing area
Graphics2D g2 = (Graphics2D) g;
PDFPage page = file.getPage(pagenum);
double pwidth = format.getImageableWidth();
double pheight = format.getImageableHeight();
double aspect = page.getAspectRatio();
double paperaspect = pwidth / pheight;
Rectangle imgbounds;
if (aspect > paperaspect) {
// paper is too tall / pdfpage is too wide
int height = (int) (pwidth / aspect);
imgbounds = new Rectangle(
(int) format.getImageableX(),
(int) (format.getImageableY() + ((pheight - height) / 2)),
(int) pwidth, height);
} else {
// paper is too wide / pdfpage is too tall
int width = (int) (pheight * aspect);
imgbounds = new Rectangle(
(int) (format.getImageableX() + ((pwidth - width) / 2)),
(int) format.getImageableY(), width, (int) pheight);
}
// render the page
PDFRenderer pgs = new PDFRenderer(page, g2, imgbounds, null,
null);
try {
page.waitForFinish();
pgs.run();
} catch (InterruptedException ie) {
}
return PAGE_EXISTS;
} else {
return NO_SUCH_PAGE;
}
}
}
}
I call it with:
new PDFPrinter(file);
Everything works fine, but after I started printing the PDF-file is locked by Java. Whats wrong?? When I restart Java it works again but only one time then it's locked again.
I found another solution...
For everyone:
public static void printPdf (String filePath, String jobName) throws IOException, PrinterException {
FileInputStream fileInputStream = new FileInputStream(filePath);
byte[] pdfContent = new byte[fileInputStream.available()];
fileInputStream.read(pdfContent, 0, fileInputStream.available());
ByteBuffer buffer = ByteBuffer.wrap(pdfContent);
final PDFFile pdfFile1 = new PDFFile(buffer);
pdf_print_engine pages1 = new pdf_print_engine(pdfFile1);
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pfDefault = PrinterJob.getPrinterJob().defaultPage();
Paper defaultPaper = new Paper();
defaultPaper.setImageableArea(0, 0, defaultPaper.getWidth(), defaultPaper.getHeight());
pfDefault.setPaper(defaultPaper);
pjob.setJobName("Test");
if (pjob.printDialog()) {
// validate the page against the chosen printer to correct
// paper settings and margins
pfDefault = pjob.validatePage(pfDefault);
Book book = new Book();
book.append(pages1, pfDefault, pdfFile1.getNumPages());
pjob.setPageable(book);
try {
pjob.print();
} catch (PrinterException exc) {
System.out.println(exc);
}
}
Have fun with the Code
Tim
I have a bunch of .jpg images and I want to print them (on paper with ink), at a fixed size (in cm).
Let's say image1.png is 400x600 pixels and I want to print it at 300 dpi.
I've tried using PrinterJob and Printable implementation, but it seems I can't specify DPI.
Here is the code snippets:
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new PrintableDeck(cardDB));
PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
attr.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
attr.add(new MediaPrintableArea(8,21,210-16,296-42,MediaPrintableArea.MM));
attr.add(MediaSizeName.ISO_A4);
attr.add(new Copies(1));
attr.add(OrientationRequested.PORTRAIT);
attr.add(PrintQuality.HIGH);
//attr.add(Fidelity.FIDELITY_TRUE);
job.print(attr);
and
public class PrintableDeck implements Printable {
BufferedImage image;
public PrintableDeck(DB cardDB){
// This load an image into 'image'
BufferedImage image = cardDB.getCard(5462).getBufferedImage();
}
public int print(Graphics graphics, PageFormat pf, int page)
throws PrinterException{
if(page>0){
return NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) graphics;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
double pageHeight = pf.getImageableHeight();
double pageWidth = pf.getImageableWidth();
// This print ONLY ~596x842, as if page is 72 DPI
System.out.println("Imageable WH: "+pageWidth+" x "+pageHeight);
// This print correctly 400x600
System.out.println("Image: "+images.get(0).getWidth(null)+" x "+images.get(0).getHeight(null));
g2.drawImage(image, 0, 0, null);
g2.dispose();
return PAGE_EXISTS;
}
}
As you can see above, I have PageFormat.getImageableHeight() ~ 842 and PageFormat.getImageableWidth() ~ 595. If page would be 300 DPI, I expected these values to be much higher, about 3000 x 2500.
What I am missing?
Thank you so much.
Java sets the image's DPI to the default java 72dpi if there is no previously a defined DPI in the image's meta data, so it was better than scalling your image to its dimensions in the java 72dpi default resolution, it is better to add your 300dpi resolution to your image meta data, thus, it would be adjusted in the better resolution in the right printable area dimensions, and that is besides setting printer resolution, media size, and media printable area attributes, You may set the dpi to your saved image with such method in http://www.javased.com/?post=321736 :
private void saveGridImage(File output,BufferedImage gridImage) throws IOException {
output.delete();
final String formatName = "png";
for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
ImageWriter writer = iw.next();
ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
continue;
}
setDPI(metadata);
final ImageOutputStream stream = ImageIO.createImageOutputStream(output);
try {
writer.setOutput(stream);
writer.write(metadata, new IIOImage(gridImage, null, metadata), writeParam);
} finally {
stream.close();
}
break;
}
}
private void setDPI(IIOMetadata metadata) throws IIOInvalidTreeException {
double INCH_2_CM = 2.54;
// for PMG, it's dots per millimeter
double dotsPerMilli = 1.0 * DPI / 10 / INCH_2_CM;
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
horiz.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
vert.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
dim.appendChild(horiz);
dim.appendChild(vert);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
root.appendChild(dim);
metadata.mergeTree("javax_imageio_1.0", root);
}
Then add printing attributes such :
attr.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
attr.add(new MediaPrintableArea(8,21,210-16,296-42,MediaPrintableArea.MM));
attr.add(MediaSizeName.ISO_A4);
To have better quality of image's view and resolution.
here's my code, note I am using Scalr.
private String autoResizeImage(String image, int width, int dpi, String prefix) throws IllegalArgumentException, ImagingOpException, IOException {
File file = new File(image);
BufferedImage img = ImageIO.read(file);
BufferedImage result = Scalr.resize(img, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, width, Scalr.OP_ANTIALIAS);
File outputfile = new File(prefix);
PNGEncodeParam penc = PNGEncodeParam.getDefaultEncodeParam(result);
double meter2inchRatio = 1d / 0.0254d;
int dim = (int) (dpi * meter2inchRatio) + 1;
penc.setPhysicalDimension(dim, dim, 1);
// resize orginal image
JAI.create("filestore", result, outputfile.getAbsolutePath(), "PNG", penc);
return outputfile.getAbsolutePath();
}
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.