Printing silently from Spring MVC/Jasper Application - spring-mvc

This is very abstract question.
I'm working on a Spring MVC Web Application which has to deal with lot of invoice printing continuously. Currently When the invoice is saved, the spring controller delegates the invoice id to the jasper pdf generation service which prepares the pdf. After the pdf gets downloaded, the user manually prints it.
I need a way to print the invoice silently when the user saves the invoice.
Any ideas?

Since you are exporting to PDF it is possible. You need to add a JRPdfExporterParameter.PDF_JAVASCRIPT parameter to your JRPdfExporter instance with the value "this.print({bUI: true,bSilent: false,bShrinkToFit: true});". For Example:
protected static byte[] exportReportToPdf(JasperPrint jasperPrint) throws JRException{
JRPdfExporter exporter = new JRPdfExporter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
exporter.setParameter(JRPdfExporterParameter.PDF_JAVASCRIPT, "this.print({bUI: true,bSilent: false,bShrinkToFit: true});");
exporter.exportReport();
return baos.toByteArray();
}
This actually adds the JavaScript to the PDF. When the PDF is opened it is ran, and will send it the print queue. It should be noted that this should be used sparingly as it is not generally considered to be nice to do this automatically for your users. When I have used it in an app, we had to buttons for each report. An Export button, that does not contain the JavaScript, and a Print button that did. That way users that wanted it to just print it would do so, and those that wanted a digital copy had that also.

Related

How to get query parameters value from deep link while dynamic link created using AppInvitation class using Firebase?

In my app, I am sending invitation to people to join my app. I am using AppInvitation IntentBuilder Class to create Intent. After these steps, one URL-link gets generated that we can send to invitees.
I have written below code to generated that link and start the activity to send the link. I am able to send invites and able to successfully launch the app by clicking the dynamiclinks. Both the dynamically and manually created ones.
IDictionary<string, string> values = new Dictionary<string, string>();
values.Add("utm_campaign", "Health");
values.Add("utm_medium", "GoIbibo");
values.Add("ad", "1");
values.Add("credit", "50");
values.Add("utm_source", "Yahoo");
values.Add("afl", "https://www.facebook.com");
var intentbuidl = new AppInviteInvitation.IntentBuilder(MainActivity.mainActivity.GetString(Resource.String.invitation_title))
.SetMessage(MainActivity.mainActivity.GetString(Resource.String.invitation_message))
.SetDeepLink(Android.Net.Uri.Parse(MainActivity.mainActivity.GetString(Resource.String.invitation_deep_link)))
.SetAdditionalReferralParameters(values)
.Build();
MainActivity.mainActivity.StartActivityForResult(Intent.CreateChooser(intentbuidl, "Install"),0);
Generated link: https://aku4q.app.goo.gl/i/619426442529-4a4105fd-33ea-4b0f-bf07-6f4063eef8f8
So my question is, when do invitees open the app using this link? Can we be able to get these additional parameters which I have set using IDictionary from the above generated link?
To my knowledge, no. This is one of the limitations of Firebase deep linking — you can't pass custom parameters and need to use the URL string for everything.
You could check out Branch.io (full disclosure: I'm on the Branch team) for an alternative approach that does allow custom parameters.

Mail Merge Feature for a CRM web-app made in asp.NET

We're working on a web based CRM for my company in ASP.net. I frequently have to send newsletters to all of my customers, and it becomes tedious to manually copy all of their addresses. What I would like is a feature to send one mail to all of my customers, taking their addresses from our contacts database, similar to a mail merge.
My developer said that he can do this for Emails, but not for physical mail. His reasoning behind this is that he can write a script that sends the mails to all customers one by one, but he can only give one single print command, which would only be able to print the current contents of the page. Therefore, he would not be able to print the individual letters for all of the customers.
Does anyone have ideas on how this would be possible? E.g. printing the page in such a way that each letter would be printed on a seperate page, or another way to automatically print all of the letters (with the mailmerged fields)?
Any help will be appreciated. If you require more details, please tell me.
A webpage is not the right solution to physically print letters. What you need to produce is a report that would generate a PDF file. This report will generate a PDF document with a different customer address on each page. Try using Microsoft Reporting Services, it is included in SQL Server. Crystal Reports is also a popular reporting solution too.
Also, you will have a hard time printing the stylized contents of your nice looking e-mail in the reporting solutions mentioned above. Consider using the report only as the cover letter of your mail piece.
One possible solution is to use 3rd party library for creation of individual letters for your customers. Docentric Toolkit is .NET tool that solves exactly your problem. We are using it for creating individual letters for customers and they all are merged in one file so that printing is done only once. Users can even create or change template documents.
Next you would have to create a template document in MS Word where you would include fixed content and placeholders for variable content which would be filled in at runtime with customer information.
After processing the data in .NET application you merge the data with the template document (see code snippet below). Your final document will be one file with letters for your customers, each on its own page. This file can then be sent to the printer with one print command.
I am attaching a code snippet of a Main method of the sample console application. The project has references to Entity Framework and Docentric’s dlls and uses entity model of Northwind database.
As you can see, it is really easy to prepare the data and merge it with template document. Solution is suitable for ASP.NET and MVC applications because you don’t need Microsoft Office installed on the server.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Docentric.Word;
namespace DisplayCustomers
{
class Program
{
static void Main(string[] args)
{
// first we read customers - in the example we select only customers
// from USA and Canada and order them by country and customer name
List<Customers> customerList = new List<Customers>();
using (var db = new NORTHWNDEntities())
{
customerList = db.Customers
.OrderBy(o => o.Country)
.ThenBy(o => o.CompanyName)
.Where(w => w.Country == "USA" || w.Country == "Canada")
.ToList();
}
// next we merge customers data with the template and generate final document;
string templateDoc = #"C:\Test\Templates\CustomerLetter1_templ.docx";
string outputDoc = #"C:\Test\FinishedLetters\CustomerLetters1.docx";
DocumentGenerator dg = new DocumentGenerator(customerList);
DocumentGenerationResult result = dg.GenerateDocument(templateDoc, outputDoc);
}
}
}

Java Servlet Download muptiple csv files

I have a report which displays some information in a report and I have link in the report to export to CSV. To download the csv file what we are doing is ,
public class ReportServlet extends XYXServlet{
public void service(HttpServletRequest req, HttpServletResponse res) throws Exception {
...................
...................
res.setContentType("text/csv");
res.setHeader("Content-Disposition","attachment; filename=\""+reportName+"\"");
OutputStream out = res.getOutputStream();
// Render the report
ReportRender.renderReport(report,results,out,rtParam);
out.close();
}
}
This report is for one patient. Now I have the requirement where I have to download report for all the patient in the system. We have more than 5000 patients. It is a one time download. SO basically I should have one CSV file per patient .eg filename will be xyzreport-patientId. We are using velocity template . Basically ReportRender will take the report result and merge with the template using velocity template. like
VelocityContext c = new VelocityContext(params);
Writer w = new OutputStreamWriter(out);
template.merge(c,w);
w.flush();
So now my problem is how do I download all report for all patients at one time. Can I use one request/response to download reports for all patients?
You can use zip file creation.
Best Practices to Create and Download a huge ZIP (from several BLOBs) in a WebApp
In above example they have BLOBs to download. In your case you need to write CSV files on zipped stream. If you will process all at a time and then sending them will cause memory issue. You need to do it loop; writing on stream as soon as you read it. This will increase efficiency of output as well as will avoid memory issues.
Above question has also answer along with implementation which is submitted by one who asked question. It is tried and tested. :)

Asp.Net Display message instead of loading image for long running process

When i click on button need to display message instead of loading image for long running process.Need to show what is happening in my code behind.Like below stages
Collecting information from database..........
Generating PDF document..............
Sending e-Mail........
Done.
Note:No need to set default time for stages it need to take message from code behind and display.
Please send me any related links.
Thanks in advance.
Check out Easy incremental status updates for long requests
You could easily add a TextBox control and change the Text property by your code behind, in function of what you do.
For example:
private void Loading()
{
txtLoading.Text = "stage1.Collecting information from database";
// PUT CODE TO COLLECT INFORMATION FROM DATABASE HERE
txtLoading.Text += "\r\nstage2.Generating PDF document";
// PUT CODE TO GENERATE PDF DOCUMENT HERE
// ETC ETC
}
Hope it helps :)

Open print dialog for report from code

I am attempting to force open the print dialog so that all the user has to do is set the email address and press ok. I've found multiple tutorials on how to print a report to file or a printer without the print dialog, but that's not what I'm looking for.
Typically to email a report, the user displays the report, clicks the print icon in the tool bar, and then chooses email and sends it. I want to cut out the first two steps automatically.
This is one of my many attempts at doing this so far, but to no avail.
void emailInvoice()
{
Args args;
ReportRun rr;
Report rb;
PrintJobSettings pjs;
CustInvoiceJour record;
;
select record where record.RecId == 5637175089;
args = new Args("SalesInvoice");
args.record(record);
args.parmEnum(PrintCopyOriginal::OriginalPrint);
// Set report run properties
rr = new ReportRun(args,'');
rr.suppressReportIsEmptyMessage(true);
rr.query().interactive(false);
// set report properties
rb = rr.report();
rb.interactive(true);
// set print job settings
pjs = rr.printJobSettings();
pjs.fileName(strfmt("C:\\Users\\gbonzo\\Desktop\\%1.pdf", record.SalesId));
pjs.fitToPage(true);
// break the report info pages using the height of the current printer's paper
pjs.virtualPageHeight(-1);
// force PDF printing
pjs.format(PrintFormat::PDF);
pjs.setTarget(PrintMedium::Mail);
pjs.viewerType(ReportOutputUserType::PDF);
// lock the print job settings so can't be changed
// X++ code int the report may try to change the destination
// to the screen for example but this does not make
// sense when running a report here
pjs.lockDestinationProperties(true);
// Initialize the report
rr.init();
rr.run();
}
Thanks in advance for your help!
Have you tried to develop a RunBase standard dialog class (RunBaseBatchPrintable if you need to select the printer) that get all the dialog fields you need and from there, programatically run the report passing all the desired parameters? I'm prety sure it will work, and probably will left a cleaner code separating the report of the logic needed to the user interaction.
Read an example here:
http://waikeatng.blogspot.com.es/2010/10/using-runbasebatchprintable-class.html
You have to call the prompt() method of the ReportRun class before calling the run() method.
if (rr.prompt())
{
rr.run();
}
The prompt() method will show the print dialog. If you want it easier for your users you could use the SysMailer class, take a look to the quickSend() method.

Resources