如何将 jasperreports 子报表与 grails jasper 插件一起使用?

发布于 2024-08-31 00:07:55 字数 2292 浏览 6 评论 0原文

我想将子报表与 grails jasper 插件一起使用,我按照此网址 (http://www .grails.org/plugin/jasper)。这是我的代码:

Domain Book:

class Book {

  static belongsTo = Library

    Library library

    String title
    String author
    String publisher
    String category

    static constraints={
        title()
        author()
        publisher()
        category()
    }
}

Domain Library:

class Library {

  static hasMany = [ books : Book ]

  String name
  String adresse
  Date dateMaturity

    static constraints = {
    }

        String toString()
    {
        return name
    }
}

在我的 BookController 中,我有:

def createReport = {
    def books = Book.list()
    chain(controller:'jasper',action:'index',model:[data:books],params:params)
}

在我的 LibraryController 中,我有:< /strong>

def createReport = {
    def library = Library.list()
    chain(controller:'jasper',action:'index',model:[data:library],params:params)
}

我的 jasper 部分是:

我有一个子报告文件:books.jasper(获取书籍列表)。
还有一个 MasterReport :library.jasper(获取库列表)。

在我的 MasterReport(图书馆)中,我添加了子报告,我希望对于每个图书馆,显示它包含的书籍列表;这是我的库代码:

<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
...
<field name="books" class="java.util.Collection"/>
...
<subreport isUsingCache="true">
<reportElement x="0" y="25" width="437" height="100"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{books})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "books.jasper"]]>
</subreportExpression>
</subreport>

我有这个错误:

错误500:在插件[jasper]中执行控制器[JasperController]的操作[索引]导致异常:net.sf.jasperreports.engine.fill。 JRExpressionEvalException:计算表达式时出错:源文本:新 net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{books})
异常消息:未能延迟初始化角色集合:bookshelf.Library.books,没有会话或会话已关闭

谢谢您的帮助。

I would like to use subreports with grails jasper plugins, I followed the manual at this url (http://www.grails.org/plugin/jasper). Here is my code :

Domain Book :

class Book {

  static belongsTo = Library

    Library library

    String title
    String author
    String publisher
    String category

    static constraints={
        title()
        author()
        publisher()
        category()
    }
}

Domain Library :

class Library {

  static hasMany = [ books : Book ]

  String name
  String adresse
  Date dateMaturity

    static constraints = {
    }

        String toString()
    {
        return name
    }
}

In my BookController, I have :

def createReport = {
    def books = Book.list()
    chain(controller:'jasper',action:'index',model:[data:books],params:params)
}

In my LibraryController, I have :

def createReport = {
    def library = Library.list()
    chain(controller:'jasper',action:'index',model:[data:library],params:params)
}

My jasper part is :

I have a SubReport file : books.jasper (get a list of books).
Also a MasterReport : library.jasper (get a list of library).

In my MasterReport(library), I added subreport, I would like, for each library, show list of books it contains ; here is my library code :

<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
...
<field name="books" class="java.util.Collection"/>
...
<subreport isUsingCache="true">
<reportElement x="0" y="25" width="437" height="100"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{books})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "books.jasper"]]>
</subreportExpression>
</subreport>

And I have this error :

Error 500: Executing action [index] of controller [JasperController] in plugin [jasper] caused exception: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression : Source text : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{books})
Exception Message: failed to lazily initialize a collection of role: bookshelf.Library.books, no session or session was closed

Thank you for help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

九命猫 2024-09-07 00:07:55

Jasper 报告只需要对象列表。它不理解 GORM 查询。因此,我们所做的方法是创建一个单独的对象列表,将其命名为“查看对象”,然后将它们发送到 jasper 报告而不是域类。

 class LibraryVO {
   List books
   String name
   String adresse
   Date dateMaturity
  }

 class bookVO {
  String title
    String author
    String publisher
    String category
  }

您可以像这样初始化列表

 List data=[]

 LibraryVo libVo= new LibraryVO(...) // inalise it here
 libVo.books = [new BookVO(),new BookVO()]

 data << libVO

并将列表传递给 jasper 控制器

(chain(controller:'jasper',action:'index',model:[data:data],params:params).

Jasper reports just expects the list of objects. It doesn't understand GORM queries. So the way we do is by creating a separate list of objects which we name as 'View Objects' and then send them to jasper reports instead of domain classes.

 class LibraryVO {
   List books
   String name
   String adresse
   Date dateMaturity
  }

 class bookVO {
  String title
    String author
    String publisher
    String category
  }

You can initializ the list like

 List data=[]

 LibraryVo libVo= new LibraryVO(...) // inalise it here
 libVo.books = [new BookVO(),new BookVO()]

 data << libVO

And pass the list to jasper controller

(chain(controller:'jasper',action:'index',model:[data:data],params:params).
不奢求什么 2024-09-07 00:07:55

我发现了问题:

在我的图书馆域中,我只是添加了一个带有“书籍惰性:假”的映射:

class Library {

  static hasMany = [ books : Book ]

  String name
  String adresse
  Date dateMaturity

    static constraints = {
    }

    static mapping = {
    books lazy: false
  }

        String toString()
    {
        return name
    }
}

现在,我的报告没有任何麻烦!


grails jasper 插件使用链将模型从一个操作链接到下一个操作 (chain(controller:'jasper',action:'index',model:[data:library],params:params)之后

,在 jasper 控制器中,我们通过以下行获取模型:

def testModel = this.getProperties().containsKey('chainModel')?chainModel:null

出于某种原因,在图书馆集合中,我们在图书列表上出现错误,例如:org.hibernate.LazyInitializationException:无法延迟初始化集合 - 没有会话或会话 通过使用“lazy: false”,我们拉取

域类的所有其他实例。

是否有其他方法可以解决此问题?

I find the issue :

In my Library domain, I just add a mapping with "books lazy: false" :

class Library {

  static hasMany = [ books : Book ]

  String name
  String adresse
  Date dateMaturity

    static constraints = {
    }

    static mapping = {
    books lazy: false
  }

        String toString()
    {
        return name
    }
}

And now, I have my report witout troubles !


The grails jasper plugin use chain to chains the model from one action to the next (chain(controller:'jasper',action:'index',model:[data:library],params:params).

After, in jasper controller we get the model by this line :

def testModel = this.getProperties().containsKey('chainModel')?chainModel:null

For some reason, in Library collection, we have an error on books list, eg : org.hibernate.LazyInitializationException: failed to lazily initialize a collection - no session or session was closed

By using "lazy: false", we pull all other instances of the domain class.

Is there another way to fix this issue ?

只是在用心讲痛 2024-09-07 00:07:55

LazyInitializationException 是因为 testModel 中的对象未附加到当前的 hibernate 会话。我刚刚通过破解 JasperController 解决了这个问题,如下所示:

class JasperController {
    JasperService jasperService

    // We need this to access the current hibernate session
    def sessionFactory

    def index = {
        println(params)

        def testModel = this.getProperties().containsKey('chainModel') ? chainModel : null

        // Re-attach model objects to avoid LazyInitializationException.
        def session = sessionFactory.getCurrentSession()
        testModel?.data?.each
        {
            session.update(it)
        }

        JasperReportDef report = jasperService.buildReportDefinition(params,            request.getLocale(), testModel)
        generateResponse(report)
    }

...等等。这会重新附加模型对象,避免 LIE(无需急于获取)

The LazyInitializationException is because the objects in testModel are not attached to the current hibernate session. I've just got around this by hacking the JasperController as follows:

class JasperController {
    JasperService jasperService

    // We need this to access the current hibernate session
    def sessionFactory

    def index = {
        println(params)

        def testModel = this.getProperties().containsKey('chainModel') ? chainModel : null

        // Re-attach model objects to avoid LazyInitializationException.
        def session = sessionFactory.getCurrentSession()
        testModel?.data?.each
        {
            session.update(it)
        }

        JasperReportDef report = jasperService.buildReportDefinition(params,            request.getLocale(), testModel)
        generateResponse(report)
    }

... and so on. This re-attaches the model objects, avoiding the LIE (without having to eager fetch)

花辞树 2024-09-07 00:07:55

您可以使用 jasper 报告来调用您的 gorm,但是您需要将报告的语言设置为groovy,而不是默认的 java。然后,如果您使用子报表,则需要禁用 jasper 报表多线程并添加其他 jar。它工作得非常完美。

You can use a jasper report to call your gorm but you need to set the language for the report to groovy not java as it's default. Then if you use subreports you need to disable jasper report multithreading and add additional jars. It's just work perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文