I am trying to send some text to a printer. I need just the text printed, wrapped at the page margin and flowing to another page if necessary.
Here is a minimal example of what I am doing now:
#FXML
private void print() {
TextArea printArea = new TextArea(textArea.getText());
printArea.setWrapText(true);
printArea.getChildrenUnmodifiable().forEach(node -> node.setStyle("-fx-background-color: transparent"));
printArea.setStyle("-fx-background-color: transparent");
PrinterJob printerJob = PrinterJob.createPrinterJob();
if (printerJob != null && printerJob.showPrintDialog(textArea.getScene().getWindow())) {
if (printerJob.printPage(printArea)) {
printerJob.endJob();
// done printing
} else {
// failed to print
}
} else {
// failed to get printer job or failed to show print dialog
}
}
What ends up printing is a gray background that seems to be the control itself, along with the scrollbar. Am I approaching this the wrong way? I feel like I'm fighting against the API by tweaking and printing a control instead of just sending the text to be printed.
The example image below was taken from my cell phone camera, so the white paper ends up looking a bit light-gray, but you can still see the gray background from the control and the scrollbar.
Instead of a TextArea, print a TextFlow:
private void print() {
TextFlow printArea = new TextFlow(new Text(textArea.getText()));
PrinterJob printerJob = PrinterJob.createPrinterJob();
if (printerJob != null && printerJob.showPrintDialog(textArea.getScene().getWindow())) {
PageLayout pageLayout = printerJob.getJobSettings().getPageLayout();
printArea.setMaxWidth(pageLayout.getPrintableWidth());
if (printerJob.printPage(printArea)) {
printerJob.endJob();
// done printing
} else {
System.out.println("Failed to print");
}
} else {
System.out.println("Canceled");
}
}
Notice that the TextFlow's maxWidth needs to be set using the PrinterJob's page layout, after the print dialog has been shown.
Related
I am try to print text from text Area using JavaFX Printer(Like in notepad printing feature). I want to print that text without textArea background styles. So I try it with another text area. I wrap its text for avoid x bar overflow. But, I can't find a way to avoid y bar overflow. also I can't hide the background. can some one help or give a subjections for this or any other way. This is my current code. Also I try to hide scroll bars using css. but it did't support. I want to print only the text.
TextArea txtArea = new TextArea("This is some long text..");
public void printText() {
PrinterJob job = PrinterJob.createPrinterJob();
if(job == null) {
System.out.println("Error");
return;
}
boolean proseed = job.showPrintDialog(root.getScene().getWindow());
JobSettings ss1 = job.getJobSettings();
PageLayout pageLayout1 = ss1.getPageLayout();
double pgW1 = pageLayout1.getPrintableWidth();
double pgH1 = pageLayout1.getPrintableHeight();
TextArea tempTxtArea = new TextArea(txtArea.getText());
tempTxtArea.setPrefSize(pgW1, pgH1);
tempTxtArea.setWrapText(true);
tempTxtArea.setId("tempScroolBar");
if(proseed) {
boolean printed = job.printPage(tempTxtArea);
if (printed) {
job.endJob();
} else {
System.out.println("Fail");
}
}
}
this is my css file
#tempScroolBar > .scroll-pane {
-fx-vbar-policy: never;
-fx-hbar-policy: never;
}
Update
I updated my code. But now I have another problem. I changed TextArea to Label and to print all the content(avoid y bar overflow) I want to get number of the pages. But it doesn't return height(always return 0). Then I refer https://stackoverflow.com/a/21075734/13862869 and I set It to the Scene. Without add the label to the new Scene it doesn't give the width. But when I set the label to the Scene only three '.' are print in my document. Can some one help me to solve this...
public void printText() {
PrinterJob job = PrinterJob.createPrinterJob();
if(job == null) {
System.out.println("Error");
return;
}
boolean proseed = job.showPrintDialog(root.getScene().getWindow());
JobSettings ss1 = job.getJobSettings();
PageLayout pageLayout1 = ss1.getPageLayout();
double pgW1 = pageLayout1.getPrintableWidth();
double pgH1 = pageLayout1.getPrintableHeight();
HBox h = new HBox();
Label tempText = new Label();
tempText.setPrefWidth(pgW1);
tempText.setWrapText(true);
tempText.setText(txtArea.getText());
h.getChildren().add(tempText);
Scene s = new Scene(h); // when i remove this line again text can print
tempText.applyCss();
double fullLabelHeight = tempText.prefHeight(-1);
int numberOfPages = (int) Math.ceil(fullLabelHeight/ pgH1);
if(proseed) {
job.printPage(tempText);
job.endJob();
}
}
I am using pdfbox 2.0.21 to (physically) print PDF files that may have mixed page sizes, including nonstandard sizes such as 8.7"x11.3" which would print on legal size or larger sheets without scaling. The pdfs are created by many different employees in different ways (Acrobat DC, saving from Word, Print-to-pdf, generated by our document system...) and sent to my team to print and mail. The volume does not allow us to inspect them individually, ultimately we point our app at a folder and it will print everything there. I would prefer to create a PrinterJob or PDFPageable that automatically scaled all pages as needed, but can't get it to work.
public class PDPrn {
public static void main(String[] args) {
try (PDDocument pdf = PDDocument.load(new File("foo.pdf"))) {
PrinterJob job = PrinterJob.getPrinterJob();
Paper paper = new Paper();
Paper.setSize(612, 792); // letter size
paper.setImageableArea(36, 36, paper.getWidth() - 72, paper.getHeight() - 72); // 0.5in margins
PageFormat format = new PageFormat();
format.setPaper(paper);
PDFPageable pageable = new PDFPageable(pdf);
//doesn't scale down pages
//printer will ask for legal and cutoff bottom when forced to use letter
pageable.append(new PDFPrintable(pdf, Scaling.SCALE_TO_FIT), format);
job.setPageable(pageable);
try {
job.print();
} catch (PrinterException pe) {
}
pdf.close();
} catch (IOException ioe) {
}
}
}
Failing that I tried walking each page and directly scaling down anything larger than letter, but that moves the content around on the page in baffling ways.
public class PDPrn {
public static void main(String[] args) {
try (PDDocument pdf = PDDocument.load(new File("foo.pdf"))) {
PrinterJob job = PrinterJob.getPrinterJob();
PDFPageable pageable = new PDFPageable(pdf);
PDPageTree tree = pdf.getDocumentCatalog().getPages();
Iterator<PDPage> iterator = tree.iterator();
while (iterator.hasNext()) {
PDPage page = iterator.next();
if (page.getMediaBox().getWidth() !=612 || page.getMediaBox().getHeight() != 792) {
PDPageContentStream contentStream = new PDPageContentStream(pdf, page,
PDPageContentStream.AppendMode.PREPEND, false);
//these are the wrong scaling factors but they do shrink oversized pages
//however the shrunk content is moved far down the page and runs off the bottom
//printer still asks for legal and cuts off bottom when forced to use letter
//edit: these floats should probably be smaller
//to account for margins, but the result is still
//offset significantly below the upper left
contentStream.transform(Matrix.getScaleInstance(612f / page.getMediaBox().getWidth(),
792f / page.getMediaBox().getHeight()));
//round figures, a large positive Y moves the content upward
//but not cleanly to the upper left
//whereas a large negative Y moves the content down and cuts off the bottom
//but does print on letter without the printer complaining about size
contentStream.transform(Matrix.getTransformInstance(0f, 250f);
contentStream.close();
}
}
job.setPageable(pageable);
try {
job.print();
} catch (PrinterException pe) {
}
pdf.close();
} catch (IOException ioe) {
}
}
}
Using an attribute set with various combinations of MediaName, MediaSizeName, and MediaTray constants also resulted in no reduction, the printer stops and asks for legal paper, and cuts off the bottom when forced to letter.
How can I use pdfbox 2.0 to correctly scale down individual oversized pages to letter size as they are being printed?
Edit: By setting the page's MediaBox to PDRectangle.LETTER, I'm able to ensure that the printer will not ask for legal paper and that the origin of the content stream in the lower left corner is visible. Now it's just a matter of using the right math to get the scaling factors and perhaps affecting the margins, with ImageableArea or CropBox?
public class PDPrn {
public static void main(String[] args) {
try (PDDocument pdf = PDDocument.load(new File("foo.pdf"))) {
PrinterJob job = PrinterJob.getPrinterJob();
PDFPageable pageable = new PDFPageable(pdf);
PDPageTree tree = pdf.getDocumentCatalog().getPages();
Iterator<PDPage> iterator = tree.iterator();
while (iterator.hasNext()) {
PDPage page = iterator.next();
if (page.getMediaBox().getWidth() !=612 || page.getMediaBox().getHeight() != 792) {
PDPageContentStream contentStream = new PDPageContentStream(pdf, page,
PDPageContentStream.AppendMode.PREPEND, false);
//these are the wrong scaling factors but they do shrink oversized pages
contentStream.transform(Matrix.getScaleInstance(0.5f,0.5f));
page.setMediaBox(PDRectangle.LETTER); // make the page letter size with shrunk content origin in lower left
contentStream.close();
}
}
job.setPageable(pageable);
try {
job.print();
} catch (PrinterException pe) {
}
pdf.close();
} catch (IOException ioe) {
}
}
}
Setting a new MediaBox size is indeed enough to push the scaled content stream inside the smaller page. Comparing the dividends of source width/height and target width/height allows me to find a suitable scaling factor to apply to both sides, maintaining aspect ratio. The resulting margins from the pages themselves look acceptable for our use so I'm not worrying about fine control now, just setting the paper to 0 margin and letting it go. SHRINK_TO_FIT in the PDFPrintable constructor doesn't seem to be doing anything, I'm not sure what circumstances it has an effect under.
public class PDPrn {
public static void main(String[] args) {
try (PDDocument pdf = PDDocument.load(new File("foo.pdf"))) {
PrinterJob job = PrinterJob.getPrinterJob();
PDPageTree tree = pdf.getDocumentCatalog().getPages();
Iterator<PDPage> iterator = tree.iterator();
while (iterator.hasNext()) {
PDPage page = iterator.next();
if (page.getMediaBox().getWidth() > 612 || page.getMediaBox().getHeight() > 792) {
float fWidth = 612f / page.getMediaBox().getWidth();
float fHeight = 792f / page.getMediaBox().getHeight();
float factor = 0f;
if (fWidth > fHeight) {
factor = fHeight;
} else {
factor = fWidth;
}
PDPageContentStream contentStream = new PDPageContentStream(pdf, page,
PDPageContentStream.AppendMode.PREPEND, false);
contentStream.transform(Matrix.getScaleInstance(factor, factor));
contentStream.close();
page.setMediaBox(PDRectangle.LETTER);
}
}
Paper paper = new Paper();
paper.setSize(612, 792);
paper.setImageableArea(0, 0, 612, 792);
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
Book book = new Book();
book.append(new PDFPrintable(pdf, Scaling.SHRINK_TO_FIT), pageFormat, pdf.getNumberOfPages());
job.setPageable(book);
try {
job.print();
} catch (PrinterException pe) {
}
pdf.close();
} catch (IOException ioe) {
}
}
}
I want to use print product information on label printer. I have Zebra TLP 2844 This printer support EPL2 programming language. When I want to print non-ASCII character printer just print "?" instead of the correct character. What I did?
First I created a simple text file with the below content
əğüçşıö
and press CTRL+P to print. Output is ok printer print all characters normally.
But when I use EPL2 commands like below
N
A220,120,0,4,1,1,N,"əğçşıüö"
P1
My printer gives the below output
??ç??üö
How can I solve this problem? I use java print api to send command to my printer.
And this my code
PrinterJob pj = PrinterJob.createPrinterJob();
Doc doc = new SimpleDoc(sb.toString().getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
boolean result = false;
javax.print.PrintService printService = PrintServiceLookup.lookupPrintServices(null, null)[0];
try {
printService.createPrintJob().print(doc, null);
} catch (PrintException e) {
e.printStackTrace();
}
PrinterJob pj = PrinterJob.createPrinterJob();
Doc doc = new SimpleDoc(sb.toString().getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
boolean result = false;
javax.print.PrintService printService = PrintServiceLookup.lookupPrintServices(null, null)[0];
try {
printService.createPrintJob().print(doc, null);
} catch (PrintException e) {
e.printStackTrace();
}
Its not an issue with the code it's an issue with the printer. Most printers don't include those characters in their standard font set. You either need to use the character's hex to call them or, if they're not included on the font set on the printer, download a different font.
We are trying to print through java on dot matrix printer. We have created the Paper object with custom size. But when it goes to printer, it doesn't take the custom size. It takes either 11 inches or 12 inch size. Below is the code which we are using. Please suggest the solution.
PrinterJob job = PrinterJob.getPrinterJob(); // Get a PrinterJob.
PageFormat format = job.defaultPage(); // Get the default page format, then ask the user to customize it.
Paper paper = format.getPaper(); // Note: Custom size of paper should be supported by attach Printer.
paper.setSize((PaperWidth*72),
(PaperHeight*72)); // Set Custom size of the Paper.
paper.setImageableArea(MarginLeft*72, MarginTop*72,
paper.getWidth() - MarginRight*72 - MarginLeft*72,
paper.getHeight()- MarginBottom*72 - MarginTop*72);
System.out.println(paper.getHeight());
format.setPaper(paper); // Set the paper.
PageFormat pf = job.validatePage(format);
Book bk = new Book(); // Set up a book, with exact no. of pages to be printable.
bk.append(new TestClass(), pf, numPages);
job.setPageable(bk); // Pass the book to the PrinterJob
////// OR set printable without book.
//// job.setPrintable(new TestClass(),format);
if (job.printDialog()) // Put up the dialog box
{
try
{
job.print(); // Print the job if the user didn't cancel printing.
}
catch (PrinterException ex)
{
}
I am printing a Jpanel and its working fine, but now I need the print dialog box, which always appear when the print button is clicked. It suppose to go like, when user press print button the default printer should start printing the job with out coming up with a print dialog box. Here is the code, I am using,
Paper paper = new Paper();
paper.setImageableArea(0, 0, 153, 243);
paper.setSize(243, 154);
PageFormat format = new PageFormat();
format.setPaper(paper);
format.setOrientation(PageFormat.LANDSCAPE);
printjob.setPrintable(printable, format);
if (printjob.printDialog() == false)
return;
try {
printjob.print();
} catch (PrinterException ex) {
System.out.println("NO PAGE FOUND." + ex);
}
Thanks.
did you call setPrintService() on printjob?
Or try using printjob.getPrinterJob() to get an instance associated with the default printer.