1

I need a really stupid thing but I'm stuck. I need basically to render a gsp page and save the rendering locally on server side inside a folder I created under web-app/.

Basically the output of this:

    render(view: "report-test") 

must be saved in a file as example report-test.html inside a folder locate in web-app/report/

any good advice?

thanks a lot

UPDATE - EXPLANATION Thanks a lot to everyone. Let me explain what I'm trying to do, hopefully there is a better solution. I bet there is, I'm still a newbie in grails. I'm trying to print a report using print-css and Price software that helps me to create a pdf. So my idea was to create the HTML file dynamically using a gsp, and followinf the print-css rules then save it locally on the server side then execute a command (with Price) that create my pdf file and return back the pdf file to the browser.

UPDATE I need to use css but not to be used inside the html but as part of Price software command. http://www.princexml.com/ So basically the gps rendered is an html without any css applied, then when I run the command to create the pdf I specify the css file to apply. As example:

     prince -s pdf-styles.css book.html builds/book.pdf

UPDATE/2 - CLOSE

thanks to shutgunNinja see his pseudo code in his post below, here the code I'm going to use:

class YourController {
   def printHtml() {
       render(view: "report-test")
   }
   def buildReport() {
        String basePath = applicationContext.getResource("/").getFile().toString()
        def url = new URL("http://localhost:8080/PrjName/report/printHtml)
        def data = url.getText()
        def file = new File("${basePath}/reportFolder/report.html")
        file.createNewFile()
        FileUtils.writeStringToFile(file, data)
    }
}

So as wrote before by shutgunNinja, I call buildReport() which call the URL to get the html file. I'd like to add few advices:

  • Be careful if you are using some security framework, like spring security, you must be able to call that page without auth, otherwise instead of the file you requested you see a login page
  • I add the basepath var where I stored the right address to access web-app directory
OrlandoL
  • 898
  • 2
  • 12
  • 32
NiBE
  • 857
  • 2
  • 16
  • 39
  • Out of curiosity, why do you need to use this approach, as opposed to having a dynamic page that can be requested and filled in? – Shotgun Ninja May 14 '15 at 15:21
  • That being said, if you need to use this approach, one thing that could work (though it's probably not best practice) is to set up a controller method to populate that page, then manually fetch the page from the controller method URL as described [here](http://stackoverflow.com/a/943931/410342), before writing the page contents to a file as described [here](http://stackoverflow.com/a/6800339/410342). – Shotgun Ninja May 14 '15 at 15:30
  • well it seems like that but it's not. you have to provide an html file and a css file to Price software and it will do the trick as example this code creates a pdf: prince -s pdf-styles.css book.html builds/book.pdf – NiBE May 14 '15 at 15:45
  • Oh, good. Yeah, I forgot to mention making sure whatever you're using for security gets bypassed by the action when called internally. I've run into that problem when doing this for automated report generation in the past. Nice catch! – Shotgun Ninja May 15 '15 at 13:57

2 Answers2

1

The rendering is done to the Output stream of the HttpResponse. It should found as: response.outputStream

One thing you could do, is swap the 'response' object with something that has outputStream = StringOutputStream or FileOutputStream.

Do this swap before you invoke any kind of "output" operation on the response pojo.

UPDATE: Sounds like you want the output that's rendered by the Browser (because you want css to take effect, etc.).

You can't get that kind of rendering on the Server. Your best bet to create a PDF report on the Server can be found here: Create PDF with Java

Community
  • 1
  • 1
Mecon
  • 977
  • 1
  • 6
  • 17
1

Okay, I think I understand what you're trying to do, and I'm going to try to explain in more detail what I've said in the comments. I'm not sure if this is the best approach for this, but it's what I would try given no other options.

Requirement:

Take the output of a Controller method (say, report()) which renders a GSP page (via, say, render(view: "report-test")) and save it as an HTML file on the server.

Approach:

  • Preserve report() and its logic which renders the page.
  • Create another Controller method (say, buildReport()) which does not render anything on its own, but forwards back to some other page.
  • Have this buildReport() method fetch the contents of whatever URL maps to report(), and save those as a file.

Pseudocode:

class YourController {
    def report() {
        // Handle input, generate data for populating page
        render(view: "report-test")
    }
    def buildReport() {
        // Indirectly call report(), passing whatever data is needed as URL parameters manually
        def url = new URL("/path/to/action?arg1=" + params.arg1)
        def data = url.getText()
        def file = new File("/web-app/report/report.html")
        file.createNewFile()
        FileUtils.writeStringToFile(file, data)
    }
}

Keep in mind, I haven't tested this code to verify that it works or not. Modifications will almost absolutely need to be done, but it should get the point across.

EDIT: As the OP mentioned in their edits, whatever security system you're using for login filtering will need to be set to ignore report() so that you don't end up with a login screen. The same goes for any redirecting filters; this approach doesn't generally fare well with HTTP redirects or forwards, regardless of language or toolkit.

Shotgun Ninja
  • 2,540
  • 3
  • 26
  • 32