Automatic PDF Printing - Revisited

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Automatic PDF Printing - Revisited

SkipDever
This is a duplicated question.  Sorry if you are looking at this a second
time.  Here is the orignial post:

I would like to print various .fo.ftl PDF forms automatically using ECA
services.  I have written (using modified Sun code) a PDF print writer.  All
I need as a way to get a ByteArrayOutputStream from the .fo.ftl.  Using
org.ofbiz.widget.screen.ScreenFopViewHandler.render as an example, I can
easily get a ByteArrayOutputStream and print it.  Unfortunately, this
routine requires a request and a response, although the response is never
really used and can probably be null.

The question is how to get the request in the eca service.  I read the
entries at:

http://ofbiz.markmail.org/message/54mvqvnmmhnwoahy?q=Session+in+Services

where Rishi Solanki sez to just add:
<attribute name="request" mode="IN"
type="javax.servlet.http.HttpServletRequest"/>

However, that did not work.  You get an error "The following required
parameter is missing: [IN] [printInvoicePDF.request]."

So, I modified the code in in
framework\webapp\src\org\ofbiz\webapp\event\ServiceEventHandler.java

around line 220:

// don't include locale, that is also taken care of below
if ("locale".equals(name)) continue;

//Added by skipd to set up a request and response
if ("request".equals(name))
{
serviceContext.put("request", request);
continue;
}
if ("response".equals(name))
{
serviceContext.put("responset", response);
continue;
}


This all works now, but there are two problems.  I am told that it breaks
the job sandbox.  Second, I have to modifiy the service definition of the
service on which the eca runs to also include the request which kind of
messes with the purpose of an ECA.

Here is the code in ScreenFopViewHandler.render


ScreenRenderer screens = new ScreenRenderer(writer, null,
htmlScreenRenderer);
screens.populateContextForRequest(request, response, servletContext);

...
screens.getContext().put("formStringRenderer", new FoFormRenderer(request,
response));
screens.render(page);
....

ByteArrayOutputStream out = new ByteArrayOutputStream();

TransformerFactory transFactory = TransformerFactory.newInstance();

Fop fop = fopFactory.newFop(contentType, out);
Transformer transformer = transFactory.newTransformer();

// set the input source (XSL-FO) and generate the output stream of
contentType
Reader reader = new StringReader(writer.toString());
Source src = new StreamSource(reader);

...

Then, instead of:
// write to the browser
try {
out.writeTo(response.getOutputStream());
response.getOutputStream().flush();
} catch (IOException e) {
throw new ViewHandlerException("Unable write to browser OutputStream", e);
}

Changed to this:

PDFPrint(out, printerdefinition);

This all works. No browser is involved. The only issue is that the calls to
populateContextForRequest, and FoFormRenderer both require request and
response arguments. The response is only used (as far as I can tell) for
populating a beanshell, and it is never used in any of the .bsh scripts for
PDF generation. It is never used in FoFormRenderer. In any case, I would not
be writing to the browser, only capturing the output stream and sending it
on to the PDFPrint routine that I have written.

In other words, what I want to do is use the various ....fo.ftl screens for
the various forms, render them to a ByteArrayOutputStream, and send that
ByteArrayOutputStream to a routine that knows how to print the resulting PDF
stream directly to a printer.

I expect that this would be useful to lots of people. All of my customers
want it as it saves them several minutes per order, i.e., accounts payable
does not have to look up all the completed orders, and print invoices. Pick
and packing slips get printed automatically, when an ecommerce order is
placed, a pick slip is automatically printed, etc, etc.

I also would like to contribute the code back to the project and so would
like whatever method used to be "approved".

Skip

Reply | Threaded
Open this post in threaded view
|

Re: Automatic PDF Printing - Revisited

David E. Jones-2

Did you get my response to your original question?

If not, go look it up. This is already well supported OOTB by the screen widget.

-David


On Feb 18, 2011, at 9:06 AM, skip@thedevers wrote:

> This is a duplicated question.  Sorry if you are looking at this a second
> time.  Here is the orignial post:
>
> I would like to print various .fo.ftl PDF forms automatically using ECA
> services.  I have written (using modified Sun code) a PDF print writer.  All
> I need as a way to get a ByteArrayOutputStream from the .fo.ftl.  Using
> org.ofbiz.widget.screen.ScreenFopViewHandler.render as an example, I can
> easily get a ByteArrayOutputStream and print it.  Unfortunately, this
> routine requires a request and a response, although the response is never
> really used and can probably be null.
>
> The question is how to get the request in the eca service.  I read the
> entries at:
>
> http://ofbiz.markmail.org/message/54mvqvnmmhnwoahy?q=Session+in+Services
>
> where Rishi Solanki sez to just add:
> <attribute name="request" mode="IN"
> type="javax.servlet.http.HttpServletRequest"/>
>
> However, that did not work.  You get an error "The following required
> parameter is missing: [IN] [printInvoicePDF.request]."
>
> So, I modified the code in in
> framework\webapp\src\org\ofbiz\webapp\event\ServiceEventHandler.java
>
> around line 220:
>
> // don't include locale, that is also taken care of below
> if ("locale".equals(name)) continue;
>
> //Added by skipd to set up a request and response
> if ("request".equals(name))
> {
> serviceContext.put("request", request);
> continue;
> }
> if ("response".equals(name))
> {
> serviceContext.put("responset", response);
> continue;
> }
>
>
> This all works now, but there are two problems.  I am told that it breaks
> the job sandbox.  Second, I have to modifiy the service definition of the
> service on which the eca runs to also include the request which kind of
> messes with the purpose of an ECA.
>
> Here is the code in ScreenFopViewHandler.render
>
>
> ScreenRenderer screens = new ScreenRenderer(writer, null,
> htmlScreenRenderer);
> screens.populateContextForRequest(request, response, servletContext);
>
> ...
> screens.getContext().put("formStringRenderer", new FoFormRenderer(request,
> response));
> screens.render(page);
> ....
>
> ByteArrayOutputStream out = new ByteArrayOutputStream();
>
> TransformerFactory transFactory = TransformerFactory.newInstance();
>
> Fop fop = fopFactory.newFop(contentType, out);
> Transformer transformer = transFactory.newTransformer();
>
> // set the input source (XSL-FO) and generate the output stream of
> contentType
> Reader reader = new StringReader(writer.toString());
> Source src = new StreamSource(reader);
>
> ...
>
> Then, instead of:
> // write to the browser
> try {
> out.writeTo(response.getOutputStream());
> response.getOutputStream().flush();
> } catch (IOException e) {
> throw new ViewHandlerException("Unable write to browser OutputStream", e);
> }
>
> Changed to this:
>
> PDFPrint(out, printerdefinition);
>
> This all works. No browser is involved. The only issue is that the calls to
> populateContextForRequest, and FoFormRenderer both require request and
> response arguments. The response is only used (as far as I can tell) for
> populating a beanshell, and it is never used in any of the .bsh scripts for
> PDF generation. It is never used in FoFormRenderer. In any case, I would not
> be writing to the browser, only capturing the output stream and sending it
> on to the PDFPrint routine that I have written.
>
> In other words, what I want to do is use the various ....fo.ftl screens for
> the various forms, render them to a ByteArrayOutputStream, and send that
> ByteArrayOutputStream to a routine that knows how to print the resulting PDF
> stream directly to a printer.
>
> I expect that this would be useful to lots of people. All of my customers
> want it as it saves them several minutes per order, i.e., accounts payable
> does not have to look up all the completed orders, and print invoices. Pick
> and packing slips get printed automatically, when an ecommerce order is
> placed, a pick slip is automatically printed, etc, etc.
>
> I also would like to contribute the code back to the project and so would
> like whatever method used to be "approved".
>
> Skip
>

Reply | Threaded
Open this post in threaded view
|

RE: Automatic PDF Printing - Revisited

SkipDever
Thanks for the quick response.  There are indeed lots of examples, most
notibly in EmailServices.java that are suitable.

Thanks again.

Skip

-----Original Message-----
From: David E Jones [mailto:[hidden email]]
Sent: Friday, February 18, 2011 11:06 AM
To: [hidden email]
Subject: Re: Automatic PDF Printing - Revisited



Did you get my response to your original question?

If not, go look it up. This is already well supported OOTB by the screen
widget.

-David


On Feb 18, 2011, at 9:06 AM, skip@thedevers wrote:

> This is a duplicated question.  Sorry if you are looking at this a second
> time.  Here is the orignial post:
>
> I would like to print various .fo.ftl PDF forms automatically using ECA
> services.  I have written (using modified Sun code) a PDF print writer.
All

> I need as a way to get a ByteArrayOutputStream from the .fo.ftl.  Using
> org.ofbiz.widget.screen.ScreenFopViewHandler.render as an example, I can
> easily get a ByteArrayOutputStream and print it.  Unfortunately, this
> routine requires a request and a response, although the response is never
> really used and can probably be null.
>
> The question is how to get the request in the eca service.  I read the
> entries at:
>
> http://ofbiz.markmail.org/message/54mvqvnmmhnwoahy?q=Session+in+Services
>
> where Rishi Solanki sez to just add:
> <attribute name="request" mode="IN"
> type="javax.servlet.http.HttpServletRequest"/>
>
> However, that did not work.  You get an error "The following required
> parameter is missing: [IN] [printInvoicePDF.request]."
>
> So, I modified the code in in
> framework\webapp\src\org\ofbiz\webapp\event\ServiceEventHandler.java
>
> around line 220:
>
> // don't include locale, that is also taken care of below
> if ("locale".equals(name)) continue;
>
> //Added by skipd to set up a request and response
> if ("request".equals(name))
> {
> serviceContext.put("request", request);
> continue;
> }
> if ("response".equals(name))
> {
> serviceContext.put("responset", response);
> continue;
> }
>
>
> This all works now, but there are two problems.  I am told that it breaks
> the job sandbox.  Second, I have to modifiy the service definition of the
> service on which the eca runs to also include the request which kind of
> messes with the purpose of an ECA.
>
> Here is the code in ScreenFopViewHandler.render
>
>
> ScreenRenderer screens = new ScreenRenderer(writer, null,
> htmlScreenRenderer);
> screens.populateContextForRequest(request, response, servletContext);
>
> ...
> screens.getContext().put("formStringRenderer", new FoFormRenderer(request,
> response));
> screens.render(page);
> ....
>
> ByteArrayOutputStream out = new ByteArrayOutputStream();
>
> TransformerFactory transFactory = TransformerFactory.newInstance();
>
> Fop fop = fopFactory.newFop(contentType, out);
> Transformer transformer = transFactory.newTransformer();
>
> // set the input source (XSL-FO) and generate the output stream of
> contentType
> Reader reader = new StringReader(writer.toString());
> Source src = new StreamSource(reader);
>
> ...
>
> Then, instead of:
> // write to the browser
> try {
> out.writeTo(response.getOutputStream());
> response.getOutputStream().flush();
> } catch (IOException e) {
> throw new ViewHandlerException("Unable write to browser OutputStream", e);
> }
>
> Changed to this:
>
> PDFPrint(out, printerdefinition);
>
> This all works. No browser is involved. The only issue is that the calls
to
> populateContextForRequest, and FoFormRenderer both require request and
> response arguments. The response is only used (as far as I can tell) for
> populating a beanshell, and it is never used in any of the .bsh scripts
for
> PDF generation. It is never used in FoFormRenderer. In any case, I would
not
> be writing to the browser, only capturing the output stream and sending it
> on to the PDFPrint routine that I have written.
>
> In other words, what I want to do is use the various ....fo.ftl screens
for
> the various forms, render them to a ByteArrayOutputStream, and send that
> ByteArrayOutputStream to a routine that knows how to print the resulting
PDF
> stream directly to a printer.
>
> I expect that this would be useful to lots of people. All of my customers
> want it as it saves them several minutes per order, i.e., accounts payable
> does not have to look up all the completed orders, and print invoices.
Pick
> and packing slips get printed automatically, when an ecommerce order is
> placed, a pick slip is automatically printed, etc, etc.
>
> I also would like to contribute the code back to the project and so would
> like whatever method used to be "approved".
>
> Skip
>