Dynamic PDF Creation
I am using FOP to create a PDF dynamically based on user input into a web form. I don't have a problem creating the PDF only with the display of it. I need that PDF to be immediately sent to the user via a redirect or download. so something like this @Override public void onClick(){ validateUserDataFromForm(); if(!hasErrorMessage()){ ByteArrayOutputStream pdfData = factory.createPDF(startDateThatIsSetViaTheForm, endDateThatIsSetViaTheForm, reportType); // Output the steam to a page I can redirect to. // I can use a File if ByteArrayOutputStream is making things tough. // I am fine if the user gets prompted like a download link, but I want a single click to create and prompt for download. } } Here is what I have tried. 1) Making the PDF a resource: This worked initially as I needed it to, but I was having problems with the resource being reused and while the report needed to vary on each generation. Basically, I need to create the PDF, give it to the user, and then destroy the copy on the server. Every time the user clicks the create button a new PDF needs to be built and sent to the user. I also don't like this option as I don't want to waste memory by adding too many resources that are not re-used. I need the user data to update the display of the PDF when it is built, so I need the link to pass in new values to the createPDF function every time. 2) Something like this... final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); try{ OutputStream stream = response.getOutputStream(); stream.write(pdfData.toByteArray()); stream.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } That results in an error like so... [org.apache.wicket.protocol.http.WicketFilter] - closing the buffer error... Any help would be appreciated! Thanks! Jered -- View this message in context: http://www.nabble.com/Dynamic-PDF-Creation-tp21377725p21377725.html Sent from the Wicket - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org
Re: Dynamic PDF Creation
Have a look at RequestCycle#setRequestTarget. Additionnaly, you may have a look at SubmitLink, since the validation step has nothing to do in the onClick of a link jeredm wrote: I am using FOP to create a PDF dynamically based on user input into a web form. I don't have a problem creating the PDF only with the display of it. I need that PDF to be immediately sent to the user via a redirect or download. so something like this @Override public void onClick(){ validateUserDataFromForm(); if(!hasErrorMessage()){ ByteArrayOutputStream pdfData = factory.createPDF(startDateThatIsSetViaTheForm, endDateThatIsSetViaTheForm, reportType); // Output the steam to a page I can redirect to. // I can use a File if ByteArrayOutputStream is making things tough. // I am fine if the user gets prompted like a download link, but I want a single click to create and prompt for download. } } Here is what I have tried. 1) Making the PDF a resource: This worked initially as I needed it to, but I was having problems with the resource being reused and while the report needed to vary on each generation. Basically, I need to create the PDF, give it to the user, and then destroy the copy on the server. Every time the user clicks the create button a new PDF needs to be built and sent to the user. I also don't like this option as I don't want to waste memory by adding too many resources that are not re-used. I need the user data to update the display of the PDF when it is built, so I need the link to pass in new values to the createPDF function every time. 2) Something like this... final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); try{ OutputStream stream = response.getOutputStream(); stream.write(pdfData.toByteArray()); stream.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } That results in an error like so... [org.apache.wicket.protocol.http.WicketFilter] - closing the buffer error... Any help would be appreciated! Thanks! Jered - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org
Re: Dynamic PDF Creation
Thanks for the response! It seems to be working well. I am posting what I ended up with. Please let me know if you see anything that is a really bad idea. @Override public void onSubmit(){ validateCriteria(); if(!hasErrorMessage()){ MyReportFactory pdfRef = new MyReportFactory(); final ByteArrayOutputStream pdfout = pdfRef.createPDF(startDt, endDt, reportType); final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); getRequestCycle().setRequestTarget(new IRequestTarget(){ @Override public void detach(RequestCycle requestCycle) { // No need to do anything here as I already closed the stream...I think } @Override public void respond(RequestCycle requestCycle) { try{ OutputStream stream = response.getOutputStream(); stream.write(pdfout.toByteArray()); stream.flush(); pdfout.close(); }catch(IOException ex){ throw new RuntimeException(ex); } } }); } } Pills wrote: Have a look at RequestCycle#setRequestTarget. Additionnaly, you may have a look at SubmitLink, since the validation step has nothing to do in the onClick of a link jeredm wrote: I am using FOP to create a PDF dynamically based on user input into a web form. I don't have a problem creating the PDF only with the display of it. I need that PDF to be immediately sent to the user via a redirect or download. so something like this @Override public void onClick(){ validateUserDataFromForm(); if(!hasErrorMessage()){ ByteArrayOutputStream pdfData = factory.createPDF(startDateThatIsSetViaTheForm, endDateThatIsSetViaTheForm, reportType); // Output the steam to a page I can redirect to. // I can use a File if ByteArrayOutputStream is making things tough. // I am fine if the user gets prompted like a download link, but I want a single click to create and prompt for download. } } Here is what I have tried. 1) Making the PDF a resource: This worked initially as I needed it to, but I was having problems with the resource being reused and while the report needed to vary on each generation. Basically, I need to create the PDF, give it to the user, and then destroy the copy on the server. Every time the user clicks the create button a new PDF needs to be built and sent to the user. I also don't like this option as I don't want to waste memory by adding too many resources that are not re-used. I need the user data to update the display of the PDF when it is built, so I need the link to pass in new values to the createPDF function every time. 2) Something like this... final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); try{ OutputStream stream = response.getOutputStream(); stream.write(pdfData.toByteArray()); stream.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } That results in an error like so... [org.apache.wicket.protocol.http.WicketFilter] - closing the buffer error... Any help would be appreciated! Thanks! Jered - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org -- View this message in context: http://www.nabble.com/Dynamic-PDF-Creation-tp21377725p21379301.html Sent from the Wicket - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org
Re: Dynamic PDF Creation
Some little points: - on the onsubmit of a form (or any onsubmit like in button, submitlink, ajaxfallbackbutton, etc.) you don't need to verify the validity: wicket does it for you, it firsts validate the form and then call onsubmit if there is no error. Thus it means you can remove your validateCriteria and if(!haserrormessage) - you don't need to implement the whole IRequestTarget interface yourself, instead you may use some existant implementation (this requires less work for you) for exemple ResourceStreamRequestTarget (which is the most usefull in your case). There are dozens implementation of IRequestTarget in the framework, just have a look to find one which fit your needs. - this is often dangerous/expensive to add non-static inner classes (like you do with your anonymous implementation), because of serialisation of pages (reference to your top level class is hold in the inner class, and thus gets serialized if the inner instance needs to). Be aware of your session size, it is really important under heavy load. jeredm wrote: Thanks for the response! It seems to be working well. I am posting what I ended up with. Please let me know if you see anything that is a really bad idea. @Override public void onSubmit(){ validateCriteria(); if(!hasErrorMessage()){ MyReportFactory pdfRef = new MyReportFactory(); final ByteArrayOutputStream pdfout = pdfRef.createPDF(startDt, endDt, reportType); final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); getRequestCycle().setRequestTarget(new IRequestTarget(){ @Override public void detach(RequestCycle requestCycle) { // No need to do anything here as I already closed the stream...I think } @Override public void respond(RequestCycle requestCycle) { try{ OutputStream stream = response.getOutputStream(); stream.write(pdfout.toByteArray()); stream.flush(); pdfout.close(); }catch(IOException ex){ throw new RuntimeException(ex); } } }); } } Pills wrote: Have a look at RequestCycle#setRequestTarget. Additionnaly, you may have a look at SubmitLink, since the validation step has nothing to do in the onClick of a link jeredm wrote: I am using FOP to create a PDF dynamically based on user input into a web form. I don't have a problem creating the PDF only with the display of it. I need that PDF to be immediately sent to the user via a redirect or download. so something like this @Override public void onClick(){ validateUserDataFromForm(); if(!hasErrorMessage()){ ByteArrayOutputStream pdfData = factory.createPDF(startDateThatIsSetViaTheForm, endDateThatIsSetViaTheForm, reportType); // Output the steam to a page I can redirect to. // I can use a File if ByteArrayOutputStream is making things tough. // I am fine if the user gets prompted like a download link, but I want a single click to create and prompt for download. } } Here is what I have tried. 1) Making the PDF a resource: This worked initially as I needed it to, but I was having problems with the resource being reused and while the report needed to vary on each generation. Basically, I need to create the PDF, give it to the user, and then destroy the copy on the server. Every time the user clicks the create button a new PDF needs to be built and sent to the user. I also don't like this option as I don't want to waste memory by adding too many resources that are not re-used. I need the user data to update the display of the PDF when it is built, so I need the link to pass in new values to the createPDF function every time. 2) Something like this... final Response response = getRequestCycle().getResponse(); response.setContentType(application/pdf); response.setContentLength(pdfout.size()); try{ OutputStream stream = response.getOutputStream(); stream.write(pdfData.toByteArray()); stream.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } That results in an error like so... [org.apache.wicket.protocol.http.WicketFilter] - closing the buffer error... Any help would be appreciated! Thanks! Jered - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org