Did you look at the ScreenRenderer class? There is another populate context 
there that is meant for rendering a screen from a service, use that one.

Also, for examples of how this is meant to be done take a look at the send mail 
from screen service that uses screen definitions for both the HTML in the email 
and PDF attachments, all called from services and not using any of the web 
stuff.

-David


On Feb 17, 2011, at 10:43 AM, skip@thedevers wrote:

> 
> 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);
> }
> 
> 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 via email to