Can't find a Print Service using java in Windows - java

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.

Related

Decoding B64 image in Tensorflow

I'm having a terrible time dealing with image en/de-coding in TensorFlow Java. I need to handle the B64 because I have a saved model from Google AutoML vision that expects that input format. Just to be explicit the Maven import is:
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-platform</artifactId>
<version>0.4.0</version>
</dependency>
and the following minimal example shows the root issue:
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import javax.activation.MimetypesFileTypeMap;
import org.apache.commons.codec.binary.Base64;
import org.tensorflow.Graph;
import org.tensorflow.Output;
import org.tensorflow.Session;
import org.tensorflow.op.image.DecodeJpeg;
import org.tensorflow.op.image.DecodeJpeg.Options;
import org.tensorflow.types.TString;
import org.tensorflow.types.TUint8;
public class tensorflowLoadMinimal{
public static void main(String[] args) throws Exception{
// Get a public JPG locally for example purposes
String imgUrl = "https://file-examples-com.github.io/"
+ "uploads/2017/10/file_example_JPG_100kB.jpg";
String localPath = "/tmp/imgFile.jpg";
InputStream in = new URL(imgUrl).openStream();
Files.copy(in, Paths.get(localPath), StandardCopyOption.REPLACE_EXISTING);
// Sanity checking the JPG; base64 encode
File f = new File(localPath);
System.out.println("Mime Type of " + f.getName() + " is " +
new MimetypesFileTypeMap().getContentType(f));
byte[] fileBytes = Files.readAllBytes(Paths.get(localPath));
String encodedString = Base64.encodeBase64String(fileBytes);
// Make b64 string a tensor; wrap in TF structs
Graph graph = new Graph();
Session s = new Session(graph);
TString tensor = TString.scalarOf(encodedString);
Output<TString> tensorAsOut = graph
.opBuilder("Const", "imgPixels", graph.baseScope())
.setAttr("dtype", tensor.dataType())
.setAttr("value", tensor)
.build()
.<TString> output(0);
// Try to decode b64 as Jpeg... and fail
Options[] opts = new Options[1];
opts[0] = DecodeJpeg.channels(3L);
DecodeJpeg dJpg = DecodeJpeg.create(graph.baseScope(), tensorAsOut, opts);
Output<TUint8> jpgOut = dJpg.image();
s.run(jpgOut);
s.close();
}
}
It confirms I have a JPG file, and then fails to do the decoding, complaining the input format is not an image file, with succinct output:
Mime Type of imgFile.jpg is image/jpeg
...
Exception in thread "main" org.tensorflow.exceptions.TFInvalidArgumentException: Unknown image file format. One of JPEG, PNG, GIF, BMP required.
[[{{node DecodeJpeg}}]]
at org.tensorflow.internal.c_api.AbstractTF_Status.throwExceptionIfNotOK(AbstractTF_Status.java:87)
...
at orc.tensorflowLoadMinimal.main(tensorflowLoadMinimal.java:55)
Where am I going wrong?
It reads:
Unknown image file format. One of JPEG, PNG, GIF, BMP required.
Which can be fixed either by removing this superfluous part:
// Try to decode b64 as Jpeg... and fail
Options[] opts = new Options[1];
opts[0] = DecodeJpeg.channels(3L);
DecodeJpeg dJpg = DecodeJpeg.create(graph.baseScope(), tensorAsOut, opts);
Output<TUint8> jpgOut = dJpg.image();
s.run(jpgOut);
s.close();
... or by passing the expected parameter JPEG, likely into DecodeJpeg.create() or opts.

Oracle Apex, Apache PDFBox java stored procedure issues

Some background: in my app, there are some pdf reports. But, these pdf reports need to be "image" based and I was told that the report server is unable to do this. The call to the report server is done from a pl/sql procedure and the result is a blob, so now all I have at my disposal to try to do this conversion is a java stored procedure. Here is what I came up with (using Apache PDFBox):
create or replace and compile java source named "APDFUtil"
as
import oracle.sql.*;
import oracle.jdbc.driver.*;
import java.sql.*;
import oracle.sql.BLOB;
import java.sql.Blob;
import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.rendering.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
import java.awt.image.BufferedImage;
public class APDFUtil{
static OracleDriver ora = new OracleDriver();
static Connection conn;
static ByteArrayOutputStream out;
static {
try {
conn = ora.defaultConnection();
} catch (Exception ex) {}
}
public static oracle.sql.BLOB flattenPDF (oracle.sql.BLOB value) throws Exception {
if (conn == null) conn = ora.defaultConnection();
BLOB retBlob = BLOB.createTemporary(conn, true, oracle.sql.BLOB.DURATION_SESSION);
/*BEGIN TO_JPG*/
InputStream inputStream = value.getBinaryStream();
PDDocument document = PDDocument.load(inputStream);
PDFRenderer pdfRenderer = new PDFRenderer(document);
int noOfPages = document.getNumberOfPages();
BufferedImage[] pdfJPEG = new BufferedImage[noOfPages];
for (int page = 0; page < noOfPages; ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
pdfJPEG[page] = bim;
}
/*write images to new pdf*/
PDDocument documentOut = new PDDocument();
for (int page = 0; page < noOfPages;++page) {
/*get page from old document to determine width and height*/
PDPage oldPage = document.getPage(page);
Float pw = oldPage.getMediaBox().getWidth();
Float ph = oldPage.getMediaBox().getHeight();
PDRectangle rec = new PDRectangle(pw,ph);
PDPage newPage = new PDPage(rec);
documentOut.addPage(newPage);
PDImageXObject pdImage = LosslessFactory.createFromImage(documentOut, pdfJPEG[page]);
PDPageContentStream contents = new PDPageContentStream(documentOut, newPage);
contents.drawImage(pdImage, 0, 0,pw,ph);
contents.close();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
documentOut.save(out);
documentOut.close();
document.close();
/*END OF TO_JPG*/
/*out - we used to get this back from TO_JPG*/
try {
java.io.OutputStream outStr = retBlob.setBinaryStream(0);
outStr.write(out.toByteArray());
outStr.flush();
} finally {
out.close();
}
return retBlob;
}
}
the pdfbox jars have been loaded into the database
database is oracle 19c standard edition 2 release 19.0.0.0.0
I tried this code as a standalone java project with the exception that the pdf file is being read from the disk, and new file written to the disk and there it works flawlessly.
The issue:
I believe the problem starts at this line: BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
but I don't know what is causing the error or how to debug it (I came to this conclusion by a painstaking process of elimination of code and throwing exceptions) especially since it works in a standalone project. Java stored procedures are not a specialty of mine and this code was pieced together from many different sources online.

Read PDF from a URL using Selenium-WebDriver and PDF-Box

I'm trying to read the text from a PDF using Selenium-web driver and the PDFbox API. If possible I don't want to download the file, but only read the PDF from the web getting only the text of PDF into a string. The code I'm using its below, can't make to work though:
I've found examples of code to download the PDF and comparing it using the file downloaded, but none functional example extracting the text of the PDF from the URL.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class PDFextract {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get("THE URL OF SITE I CANT SHARE"); //THE URL OF SITE I CAN'T SHARE
System.out.println(driver.getTitle());
List<WebElement> list = driver.findElements(By.xpath("//a[#title='Click to open file']"));
int rows = list.size();
for (int i= 1; i <= rows; i++) {
}
List<WebElement> links = driver.findElements(By.xpath("//a[#title='Click to open file']"));
String fLinks = "";
for (WebElement link : links) {
fLinks = fLink + link.getAttribute("href");
}
fLinks = fLinks.trim();
System.out.println(fLinks); // till here the code works fine.. i get a valid url link
// the code bellow doesn't work
URL url=new URL(fLinks);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
InputStream is=connection.getInputStream();
PDDocument pdd=PDDocument.load(is);
PDFTextStripper stripper=new PDFTextStripper();
String text=stripper.getText(pdd);
pdd.close();
is.close();
System.out.println(text);
I get the error:
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 500 for URL: ***AS TOLD ABOVE, I CANT SHARE THE URL***
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at PDFextract.main(PDFextract.java:106)
Edited in 07.05.2020:
#TilmanHausherr, I've done more research, this helped out in the first part, how to read a PDF from a link: Selenium Tutorial: Read PDF Content using Selenium WebDriver
This method works:
String pdfContent = readPDFContent(driver.getCurrentUrl());
public String readPDFContent(String appUrl) throws Exception {
URL url = new URL(appUrl);
InputStream is = url.openStream();
BufferedInputStream fileToParse = new BufferedInputStream(is);
PDDocument document = null;
String output = null;
try {
document = PDDocument.load(fileToParse);
output = new PDFTextStripper().getText(document);
System.out.println(output);
} finally {
if (document != null) {
document.close();
}
fileToParse.close();
is.close();
}
return output;
}
It seems my problem its the link itself, the HTML element its '< embed >', in my case there is also a 'stream-URL':
<embed id="plugin" type="application/x-google-chrome-pdf"
src="https://"SITE
I CAN'T TELL"/file.do? _tr=4d51599fead209bc4ef42c6e5c4839c9bebc2fc46addb11a"
stream-URL="chrome-extension://mhjfbmdgcfjojefgiehjai/6958a80-4342-43fc-
838a-1dbd07fa2fc1" headers="accept-ranges: bytes
content-disposition: inline;filename="online.pdf"
content-length: 71488
content-security-policy: frame-ancestors 'self' https://*"SITE I CAN'T TELL"
https://*"DOMAIN I CAN'T TELL".net
content-type: application/pdf
Found this: 1. Download the File which has stream-url is the chrome extension in the embed tag using selenium
2. Handling contents of Embed tag in selenium python
But I still didn't manage to read the PDF with PDFbox because the element its '< embed>' and i might have to access the stream-URL.

Java Print API scaling with HTML

I am stuck at this now. I have checked almost every popular question on SO site regarding Java Print API to print HTML files (with third-party libraries such as Flying Saucer, iText, CSSBox, etc). But still couldn't get it worked at my end yet.
Here are the links of my previous questions:
https://stackoverflow.com/questions/28106757/java-print-api-prints-html-with-huge-size
How to print HTML and not the code using Java Print API?
Basically I am trying to print the HTML file that contains some CSS with <style> tag. This CSS has classes applied for <table> and <p> tags for example. I cannot change CSS code inside HTML as it should be viewed exactly with this style in browser.
Below is my program
import java.awt.print.PrinterException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.swing.JEditorPane;
public class Print {
public static void main(String[] args) throws PrintException {
String printerName = "\\\\network-path\\myPrinter";
String fileName = "C:\\log\\myLog.html";
URL url = null;
try {
url = (new File(fileName)).toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
JEditorPane editorPane = new JEditorPane();
editorPane.setEditable(false);
if (url != null) {
try {
editorPane.setPage(url);
} catch (IOException e) {
System.err.println("Attempted to read a bad URL: " + url);
}
} else {
System.err.println("Couldn't find file: " + fileName);
}
PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
printServiceAttributeSet.add(new PrinterName(printerName, null));
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, printServiceAttributeSet); // list of printers
PrintService printService = printServices[0];
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
Copies copies = new Copies(1);
pras.add(copies);
pras.add(OrientationRequested.PORTRAIT);
pras.add(MediaSizeName.ISO_A4);
try {
editorPane.print(null, null, false, printService, pras, false);
} catch (PrinterException e) {
throw new PrintException("Print error occurred:" + e.getMessage());
}
}
}
The problem is above code works and I get good print of the above HTML with proper CSS styling. But it just scales up. When the said HTML is opened in IE it looks different and when it is printed by the code what I get is different. I would prefer the print to be same as it is viewed in IE.
I also tried to get it done by passing SimpleDoc object to the printer. My printService supports below formats:
image/gif [B
image/gif java.io.InputStream
image/gif java.net.URL
image/jpeg [B
image/jpeg java.io.InputStream
image/jpeg java.net.URL
image/png [B
image/png java.io.InputStream
image/png java.net.URL
application/x-java-jvm-local-objectref java.awt.print.Pageable
application/x-java-jvm-local-objectref java.awt.print.Printable
application/octet-stream [B
application/octet-stream java.net.URL
application/octet-stream java.io.InputStream
But nothing works with SimpleDoc. I then tried converting HTML to .png using CSSBox. It works but for multipage HTML, generated image is shrunk and is not viewable for printing. With Flying Saucer and iText version 2.0.8 I get NoSuchMethodError. Also even if I get it worked (by compiling the source against the said iText version) the output is broken.
Can someone please help? I would prefer to stick to Java Print API than using any third-party. Am I missing something when using SimpleDoc object approach? What settings need to be set to print above HTML using SimpleDoc object and available printService formats.

Sending data to a printer in 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.

Categories