I need to send a pdf jasper directly to the printer, the current code PDF is delegated to the browser and therefore the user can print as many copies as desired. Must allow only print one copy, so I thought I'd send directly to printing.
I searched the forum but did not understand what would be the best solution to the issue.
Take a look at my code:
public class UtilRelatorios {
public static void imprimeRelatorio(String relatorioNome,
HashMap parametros) throws IOException, JRException {
FacesContext fc = FacesContext.getCurrentInstance();
ServletContext context = (ServletContext) fc.getExternalContext().getContext();
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
JasperPrint jasperPrint =
JasperFillManager.fillReport(
context.getRealPath("/relatorios")+ File.separator+relatorioNome+".jasper",
parametros);
//int finalPag = jasperPrint.getPages().size();
//System.out.println("page: "+finalPag);
//JasperPrintManager.printPage(jasperPrint,finalPag,false);
byte[] b = null;
//JasperPrintManager.printPage(jasperPrint, 0, false);
try {
b = JasperExportManager.exportReportToPdf(jasperPrint);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
if (b != null && b.length > 0) {
// Envia o relatório em formato PDF para o browser
response.setContentType("application/pdf");
int codigo = (int) (Math.random()*1000);
response.setHeader("Content-disposition","inline);filename=relatorio_"+codigo+".pdf");
response.setContentLength(b.length);
ServletOutputStream ouputStream = response.getOutputStream();
ouputStream.write(b, 0, b.length);
ouputStream.flush();
ouputStream.close();
}
}
}
If as seems in question you like to send the report directly to user's printer via web application, browser.
This can not be done!, you can not control the web users printer directly from the browser (excluding the use of activeX or other home made plugins)
Probably this is luck since otherwise while navigating on internet you would have people printing alot of advertising on your printer....
If instead you like to send it to a printer attached to server, this can be done!
If its the server printer please let me know and I can pass you some code.
If the client & server PC are on the same network ie LAN, you can share the client's printer on the server, then send report to it just like you'd send to a locally installed printer.
Related
public void showMessageContent(#RequestParam("mailNum") Integer mailNum, HttpServletRequest req,HttpServletResponse response) throws MessagingException, IOException {
User user = (User) req.getSession().getAttribute("user");
Message message = MailUtils.getMail(user, mailNum);
ServletOutputStream out = response.getOutputStream();
try{
if(!message.isMimeType("multipart/mixed"))
{
response.setContentType("message/rfc822");
message.writeTo(out);
}
}catch (Exception e){
e.printStackTrace();
}
}
but the Browser can't display the e-mail content,it always automatically download EML files 。
How can I deal with it?
I'm not sure that an Internet browser is able to read EML files.
When you save a mail from Mozilla Thunderbird and you want to open it in Chrome, you'll have to save it as HTML file.
What browser are you trying to use ?
I have a task to make possibility to download simple .txt files from the application using Azure Blob Storage. The code is supposed to work. I didn't write it, but it looks OK to me and from what I'll show later in this post, it really connects to the Azure, and, what's more important, it really works only when I'm testing the app on localhost, but not on the publicly available site.
These are the steps I made:
uploaded files to the storage (the underlined is one of them):
added proper link to the button that should download the attachment via REST API
of course, I've also added reference to the attachment in the database (its ID, name etc.)
here's how it looks on frontend:
And this is what I get:
I've seen somewhere that it might be caused by Azure CORS settings that don't allow the app to access the storage. Here's what I've done so far:
went to portal.azure.com and changed CORS settings like this:
found something about putting some code into the app under this Microsoft link, but it's not Java. I guess there are some analogical ways in Java:
https://blogs.msdn.microsoft.com/windowsazurestorage/2014/02/03/windows-azure-storage-introducing-cors/ . Is it necessary after the CORS rules have been added in the Azure Portal?
Also, I've found information that it may be caused by the storage access permissions. The Public Access Level is set to Container:
Not sure if it gives anything, but these are the container's properties:
What else can be the problem with the BlobNotFound error I receive? Hope I've put enough information here, but if some more is needed say in comment and I'll provide it.
This is the code that's supposed to download the attachment of this method, contained in 3 classes:
Controller class part:
#GetMapping("/download/{id}")
#ResponseStatus(HttpStatus.OK)
public void downloadAttachment(#PathVariable long id, HttpServletResponse response) throws IOException {
dataUploadRequestAttachmentService.downloadStaticAttachment(response, id);
}
Controller service class part:
public void downloadStaticAttachment(HttpServletResponse response, long id) throws IOException {
ArticleAttachment articleAttachment = this.findAttachment(id);
String mimeType = URLConnection.guessContentTypeFromName(articleAttachment.getName());
if (mimeType == null){
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", articleAttachment.getName()));
azureBlobStorageArticleAttachmentService.downloadArticleAttachment(
articleAttachment.getName(),
articleAttachment.getId(),
response.getOutputStream()
);
}
And the AzureBlobStorageArticleAttachmentService class:
public void downloadArticleAttachment(String attachmentName, Long articleId, OutputStream outputStream) {
try {
CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));
blob.download(outputStream);
} catch (URISyntaxException | StorageException e) {
e.printStackTrace();
log.error(String.format("Download article attachment %s error", attachmentName));
}
}
According to your description, please debug to check if you get the correct blob name in the code: CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));
Here is a demo about how to download blobs using Java SDK for your reference:
/// <summary>
/// download blob to memory
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
public static ByteArrayOutputStream downloadBlobToMemory(String containerName, String blobName) {
CloudStorageAccount account = null;
CloudBlobContainer container = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
account = CloudStorageAccount.parse(ConnString);
CloudBlobClient client = account.createCloudBlobClient();
container = client.getContainerReference(containerName);
container.createIfNotExists();
CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
byteArrayOutputStream=new ByteArrayOutputStream();
cloudBlockBlob.download(byteArrayOutputStream);
}catch(Exception ex) {
ex.printStackTrace();
}
return byteArrayOutputStream;
}
/// <summary>
/// download blob to local disk
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
/// <param name="filePath"> for example: C:\\Test\test.txt</param>
public static void downloadBlobToDisk(String containerName, String blobName, String filePath) {
CloudStorageAccount account = null;
CloudBlobContainer container = null;
try {
account = CloudStorageAccount.parse(ConnString);
CloudBlobClient client = account.createCloudBlobClient();
container = client.getContainerReference(containerName);
container.createIfNotExists();
CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
FileOutputStream fileOutputStream=new FileOutputStream(filePath);
cloudBlockBlob.download(fileOutputStream);
}catch(Exception ex) {
ex.printStackTrace();
}
}
Lee Liu's suggestion about the Blob name was correct when I managed to find out the correct application address. It turned out that domain address visible by user was ending with "azureedge.net", but there's a different one when I went into portal.azure.com. It caused the main problem. After that, I indeed found problem with correct Blob names in storage - because of String.format, I had to add their ID in database with a "_" sign, then they started to be downloaded with content instead of empty files.
It seems that the code was OK, it was the problem with improper address and file names.
updated question:
On server side i have a service as below, if I want to use ajax to fire the call on the client side, how I should do that?
In server:
Java/Spring
#GET
#Produces("application/vnd.ms-excel")
#Path("permissions/all/{userList}")
public Response allPermissionsExcel(#PathParam("userList") String userList) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
HSSFWorkbook wb;
try {
String[] groupList = userList.split(",");
wb = this.excelPermissionsService.getPermissionsExcelWorkbook(groupList);
wb.write(baos);
} catch (IOException e) {
e.printStackTrace();
} finally {
baos.close();
}
byte[] bytes = baos.toByteArray();
ResponseBuilder response = Response.ok(bytes);
response.header("Content-Disposition", "attachment; filename=export.xls");
return response.build();
}
In client:
$scope.exportToExcel = function() {
var promise = usersResource.getExcelPermissions($scope.userList);
promise.$promise.then(function(data) {
//I tried to convert to blob then save it with FileSaver.js, but I got an issue in converting the object to blob.
var blob = new Blob([data],
var blob = new Blob([data],
{type: "application/octet-stream"});
saveAs(blob, "exportThis.xls");
});
};
in the client side, if i use ajax (above code) to fire a call to server, and it returns an object, but nothing prompts up to download, unless I use
window.location = "url here";
to fire the call. But that's a redirect and pops up to download after all javascript ran.
Since I have some loading animations which are applied by $watch, i need to use ajax to fire the call instead of using window.location.
Can anyone help me save the "data" object excel in client side?
Thanks!
You need to use window.open without requesting an ajax
it will just open a new window and then the file will start download without affecting the current page
window.open("permissions/all/1"); // instead of window.location because it will move you to another page
You also can open it by a pop up like this
newwindow=window.open("permissions/all/1","Window name",'height=50,width=150); // this one is better because it will open a small window without hiding the current window
if (window.focus) {newwindow.focus()}
return false;
I am using Apache wicket 6.19.0, pdfbox 1.8.8, and Java 8.
The problem I am facing is I get the print dialog on screen when I deploy my application on a Windows machine, but when deployed on the Linux server it doesn't show the print dialog on screen when invoked the print functionality from UI.
Code:
public static PrintService choosePrinter() {
PrinterJob printJob = PrinterJob.getPrinterJob();
if(printJob.printDialog()) {
return printJob.getPrintService();
}else {
return null;
}
}
#Override
public File getObject() {
File file = new File("document.pdf");
file.deleteOnExit();
PDDocument document = new PDDocument();
//prepare the pdf here...
PrinterJob job = PrinterJob.getPrinterJob();
PrintService service = choosePrinter();
if(service != null){
job.setPrintService(service);
document.silentPrint(job);
}
document.close();
} catch (Exception e) {
LOGGER.error("Exception: "+e);
}
return file;
}
PrinterJob is a class from AWT, i.e. a desktop feature.
You cannot use it at the server.
Apache Wicket is a web framework so I assume your users will reach the application thru a browser. In this case you have two options:
render a good looking HTML and use JavaScript's window.print() to print it
render a PDF and stream it to the browser so that it either:
2.1. show it by using Content-Disposition: Inline response header (if the browser has PDF plugin)
2.2. ask the user to save it, by using Content-Disposition: Attachment
I am not sure whether there is a way to print the PDF with JavaScript.
This is my download code. It just starts downloading the file without asking user. I've searched multiple forums and nothing seems to work. This is code is in a backing bean attached to a commandButton.
public void doDownloadFile() {
PrintWriter out = null;
try {
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=test.csv");
out = response.getWriter();
CSVWriter writer = new CSVWriter(out);
List<String[]> stringList = new ArrayList<String[]>();
for (User user : userList) {
String[] string = {user.getEmail(), user.getName(), user.getPassword()};
stringList.add(string);
}
writer.writeAll(stringList);
out.flush();
} catch (IOException ex) {
Logger.getLogger(ViewLines.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
}
This is most likely due to the fact your browser is configured to download files of these types without prompt. The code has nothing to do with it.
The behavior of what to do with a download is 100% local, meaning it's the browser, not you, that determines what to do in that case. Whether the user's browser just dumps the file in a download folder or allows him to save it to a particular spot is entirely up to the browser.
Not much to be done.