You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by "Gooch, Allen" <go...@darden.virginia.edu> on 2003/11/17 17:10:21 UTC

Making MS Word documents available from Tapestry 3.0

I am trying to determine the best way to send a MS Word *.doc file back
to the user for handling.  After searching the archives I came across a
thread describing how it could be accomplished for MS Excel files and
started investigating. The steps detailed include:

1) Create your own SomeTypeWriter class that extends from HTMLWriter 
2) Override getContentType() in this class to return the MIME type you
want the page to have.
3) Create a new SomeTypePage class that extends BasePage
4) Override getResponseWriter(OutputStream out) in this class to return
your SomeTypeWriter
5) Override renderPage(IMarkupWriter mw, IRequestCycle rc) and use
mw.printRaw(...) to output your binary content.

This makes sense except that I/O at the IMarkupWriter level is done in
terms of PrintWriter and not OutputStream objects. As the
IMarkupWriter.printRaw(char[], int, int) API is expressed in terms of
char[] and not byte[] (my Word doc) I'm not sure how step #5 above will
work. What am I missing? Is this really the best way to achieve this
end?

-allen

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Making MS Word documents available from Tapestry 3.0

Posted by "Kevin C. Dorff" <kd...@kcp.com>.
Is the file available within the document root of your website or coming 
from a database or some such?

If it is just a file that lives within your website, why not just create 
a <a href=".../hello.doc">view the document</a>.

If it is coming from a database or some such, I would just create a 
service and use a @ServiceLink to get at it.

Kevin

Gooch, Allen wrote:

>I am trying to determine the best way to send a MS Word *.doc file back
>to the user for handling.  After searching the archives I came across a
>thread describing how it could be accomplished for MS Excel files and
>started investigating. The steps detailed include:
>
>1) Create your own SomeTypeWriter class that extends from HTMLWriter 
>2) Override getContentType() in this class to return the MIME type you
>want the page to have.
>3) Create a new SomeTypePage class that extends BasePage
>4) Override getResponseWriter(OutputStream out) in this class to return
>your SomeTypeWriter
>5) Override renderPage(IMarkupWriter mw, IRequestCycle rc) and use
>mw.printRaw(...) to output your binary content.
>
>This makes sense except that I/O at the IMarkupWriter level is done in
>terms of PrintWriter and not OutputStream objects. As the
>IMarkupWriter.printRaw(char[], int, int) API is expressed in terms of
>char[] and not byte[] (my Word doc) I'm not sure how step #5 above will
>work. What am I missing? Is this really the best way to achieve this
>end?
>
>-allen
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
>  
>




---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Making MS Word documents available from Tapestry 3.0

Posted by Marilen Corciovei <le...@nemesisit.rdsnet.ro>.
What you need is something similar to this:

package ro.nit.service.web.report;

import org.apache.log4j.Logger;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.engine.AbstractService;
import org.apache.tapestry.engine.IEngineServiceView;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.request.ResponseOutputStream;
import ro.nit.components.hTools.HibernateGlobal;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * User: len
 * Date: Oct 6, 2003
 * Time: 2:38:47 AM
 * @author <a href="mailto:marilen.corciovei@nemesisit.ro">Marilen
Corciovei</a>
 * @version $Id: ReportService.java,v 1.7 2003/10/06 01:07:39 len Exp $
 */
public class ReportService extends AbstractService{

    public static final String SERVICE_NAME = "report";

    Logger logger = Logger.getLogger(ReportService.class);
    /**
     *  Builds a URL for a service.  This is performed during the
     *  rendering phase of one request cycle and bulds URLs that will
     *  invoke activity in a subsequent request cycle.
     *
     *  @param cycle Defines the request cycle being processed.
     *  @param component The component requesting the URL.  Generally,
the
     *  service context is established from the component.
     *  @param parameters Additional parameters specific to the
     *  component requesting the EngineServiceLink.
     *  @return The URL for the service.  The URL will have to be
encoded
     *  via {@link HttpServletResponse#encodeURL(String)}.
     *
     **/
    public ILink getLink(IRequestCycle cycle, IComponent component,
Object[] parameters) {

        String[] context;
        String pageName = component.getPage().getPageName();
        String idPath = component.getIdPath();

        if (idPath != null){
            context = new String[2];
            context[1] = idPath;
            logger.debug("idPath=" + idPath);
        }
        else{
            context = new String[1];
        }

        context[0] = pageName;
        logger.debug("pageName=" + pageName);

        return constructLink(cycle, SERVICE_NAME, context, parameters,
true);
    }

    /**
     *  Perform the service, interpreting the URL (from the
     *  {@link HttpServletRequest})
     *  responding appropriately, and
     *  rendering a result page.
     *
     *
     *  @see org.apache.tapestry.IEngine#service(RequestContext)
     *  @param engine a view of the {@link org.apache.tapestry.IEngine}
with additional methods needed by services
     *  @param cycle the incoming request
     *  @param output stream to which output should ultimately be
directed
     *
     **/
    public void service(
            IEngineServiceView engine,
            IRequestCycle cycle,
            ResponseOutputStream output)
            throws ServletException, IOException {
        Object[] parameters = getParameters(cycle);

        RequestContext requestContext = cycle.getRequestContext();

        String context[] = getServiceContext(requestContext);

        String pageName = context[0];
        String idPath = (context.length == 1) ? null : context[1];
        logger.debug("pageName=" + pageName + ", idPath=" + idPath);

        IPage page = cycle.getPage(pageName);
        IComponent component = (idPath == null) ? page :
page.getNestedComponent(idPath);
        logger.debug("page=" + page.getPageName() + ", component=" +
component.getId());

        if(parameters.length < 1 || parameters == null)
            engine.reportException("Report service requires at least 1
parameter",null);

        try{
            output.setContentType("application/pdf");
            HttpServletResponse response =
cycle.getRequestContext().getResponse();

           
response.setHeader("Content-Disposition","inline;filename="+report.getReportFileName(parameters));
            // the content of the output stream is not cache-able
            response.setHeader("Cache-Control","no-cache");
            response.setHeader("Cache-Control","no-store");
            response.setHeader("Cache-Control","must-revalidate");
            response.setHeader("Cache-Control","max-age=10");
            response.setHeader("Expires","0");
            response.setHeader("Pragma","no-cache");

            HibernateGlobal global =
(HibernateGlobal)engine.getGlobal();
            report.doReport(output, parameters, global.openSession());

            //output.write(buf, 0, bytes);
        }
        catch(Throwable t){
            engine.reportException("Error generating report", t);
        }
    }

    /**
     *  Returns the name of the service.
     *
     *  @since 1.0.1
     **/
    public String getName() {
        return SERVICE_NAME;
    }
}


On Mon, 2003-11-17 at 18:10, Gooch, Allen wrote:

> I am trying to determine the best way to send a MS Word *.doc file back
> to the user for handling.  After searching the archives I came across a
> thread describing how it could be accomplished for MS Excel files and
> started investigating. The steps detailed include:
> 
> 1) Create your own SomeTypeWriter class that extends from HTMLWriter 
> 2) Override getContentType() in this class to return the MIME type you
> want the page to have.
> 3) Create a new SomeTypePage class that extends BasePage
> 4) Override getResponseWriter(OutputStream out) in this class to return
> your SomeTypeWriter
> 5) Override renderPage(IMarkupWriter mw, IRequestCycle rc) and use
> mw.printRaw(...) to output your binary content.
> 
> This makes sense except that I/O at the IMarkupWriter level is done in
> terms of PrintWriter and not OutputStream objects. As the
> IMarkupWriter.printRaw(char[], int, int) API is expressed in terms of
> char[] and not byte[] (my Word doc) I'm not sure how step #5 above will
> work. What am I missing? Is this really the best way to achieve this
> end?
> 
> -allen
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org



RE: Making MS Word documents available from Tapestry 3.0

Posted by Adam Greene <ag...@romulin.com>.
You should create a custom service, not a custom page / writer.  The service
allows direct access to the ServletResponseStream.

-----Original Message-----
From: Gooch, Allen [mailto:goocha@darden.virginia.edu]
Sent: Monday, November 17, 2003 12:10 PM
To: tapestry-user@jakarta.apache.org
Subject: Making MS Word documents available from Tapestry 3.0


I am trying to determine the best way to send a MS Word *.doc file back
to the user for handling.  After searching the archives I came across a
thread describing how it could be accomplished for MS Excel files and
started investigating. The steps detailed include:

1) Create your own SomeTypeWriter class that extends from HTMLWriter
2) Override getContentType() in this class to return the MIME type you
want the page to have.
3) Create a new SomeTypePage class that extends BasePage
4) Override getResponseWriter(OutputStream out) in this class to return
your SomeTypeWriter
5) Override renderPage(IMarkupWriter mw, IRequestCycle rc) and use
mw.printRaw(...) to output your binary content.

This makes sense except that I/O at the IMarkupWriter level is done in
terms of PrintWriter and not OutputStream objects. As the
IMarkupWriter.printRaw(char[], int, int) API is expressed in terms of
char[] and not byte[] (my Word doc) I'm not sure how step #5 above will
work. What am I missing? Is this really the best way to achieve this
end?

-allen

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org