2015-06-09 49 views
0

在我的Grails項目中,我使用PDF插件從gsp頁面生成PDF。如何爲grails創建PDF編輯器

它運行良好,但我想向用戶添加更多的功能,所以我想讓用戶編輯PDF基本模板(在gsp頁面中定義),特別是我想允許編輯模板內的文本並將其存儲在某處。

有人知道該怎麼辦?

回答

1

如果您只想更改文本,可以將編輯後的文本與用戶標識一起存儲到數據庫中,並將其加載到gsp頁面而不是標準文本中。

如果您還想更改頁面的樣式,您可以嘗試將整個gsp頁面存儲在數據庫中,並讓用戶使用HTML編輯器進行編輯。

這就是我如何與,也許有人有一個更好的主意

+0

你知道一些易於使用的HTML編輯器嗎?可以將它集成到Grails的某些gsp頁面中嗎? – FrancescoDS

1

的PDF插件的底層組件並沒有嚴格要求.gsp文件開始。它只是使用作爲字符串呈現的.gsps,並將它們提供給flyingsaucer lib。因此,您可以使用所見即所得類型編輯器來允許用戶創建html片段,以某種方式保存這些字符串,然後將它們自己提供給flyingsaucer庫。只需查看插件的包含服務方法即可。這聽起來很可怕,但它確實不是很複雜。

你可能想用自己的HTML標記來包裝用戶生成的內容,以達到理智和樣式的目的,但是你想要的想法是完全可行的。

+0

您認爲String是包含所有gsp頁面的好類型嗎? – FrancescoDS

+0

當然,String是可以的,但是您可能想要將它映射到數據庫級別的varchar以外的內容。在您的域中添加一個映射塊,如:'static mapping = {gspContent type:'text'}' – aeischeid

1

您可以擁有一種具有兩種不同方式的GSP。首先,GSP將呈現爲可編輯狀態。在這種狀態下,用戶可以在GSP的某些部分進行一些編輯。之後,GSP將呈現爲預覽狀態,用戶可以在其中檢查他在上一步中所做的修改(在此狀態下無法編輯任何內容)。最後,GSP將呈現爲PDF格式(使用Grails渲染插件)。

請注意,用戶不會編輯GSP本身。例如,您需要允許他通過HTML元素編輯文本區域。在這種情況下,我們使用WYSWYG編輯器。此編輯器允許用戶將文本設置爲粗體,斜體等。

因此,此解決方案最重要的一步是區分同一GSP中的兩個狀態。要做到這一點,你可以使用一個布爾變量(比如稱爲編輯)。如果這個變量爲真,該變量將使GSP具有允許他在文檔中執行更改的元素。另一方面,如果編輯變量爲false,則GSP將僅以文本呈現,不允許任何類型的編輯。

用戶可以選中或取消選中複選框(顯示或隱藏文檔的某些部分)並在文本區域元素中編寫或更改文本。

下面我會展示這個解決方案的工作原理。

GSP

的GSP是一個模板GSP,並且被稱爲_quote.gsp下面

的一段代碼示出了使用該編輯的變量。請注意,如果編輯= true,則會呈現textarea,並且用戶可以編輯文本。有一個可以更改的標準文本。

post變量保留用戶在編輯階段後完成的操作。我們使用JQuery序列化來獲取所有參數並將其傳遞給Grails控制器。

<p> 
    <g:if test="${editing}"> 
     <pgs:textArea html="true" autosize="true" name="fraseInicial" rows="2" cols="80"> 
      ${post?.fraseInicial?post.fraseInicial:"Conforme sua solicitação, a empresa tem a satisfação de informar-lhe os métodos e preços."} 
     </pgs:textArea> 
    </g:if> 
    <g:else> 
     ${post.fraseInicial} 
    </g:else> 
</p> 

PGS:文本是該系統的特定標籤庫和用於呈現一個所見即所得的編輯器,可以更換一個簡單的文本區的HTML元素。

與複選框一個例子:

<g:if test="${editing || post.temPrazoAnalise}"> 
    <h1> 
     Teste teste 
    </h1> 
    <g:if test="${editing}"><g:checkBox name="temPrazoAnalise" value="${!post?true:post?.temPrazoAnalise == null?false:true}"/></g:if> 
    <g:if test="${editing || post.temPrazoAnalise}"> 
     <p>Teste teste teste </p> 
    </g:if> 
</g:if> 

控制器

的previewQuote()被從AJAX調用序列化(通過JQuery)稱爲GSP的所有參數。

back()動作允許用戶從預覽狀態返回到編輯狀態。這就是我們在previewQuote()中設置session [「paramsReport」] = params的原因。通過這種方式,可以在back()中使用session [「paramsReport」]並恢復用戶更改的值。

def editQuote() { 
     def quote = Quote.get(params.id) 
     render(template: "/quote/report/quote", model: [editing:true, quote:quote]) 
    } 


    def previewQuote() { 
     Quote quote = Quote.get(params.id)   
     session["paramsReport"] = params   
     render(template: "/quote/report/quote", model: [quote:quote, post:params]) 
    } 


    def back() { 
     def quote = Quote.get(params.id) 

     if (session["paramsReport"]) { 
      render(template: "/quote/report/quote", model: [editing:true, post:session["paramsReport"], quote:quote]) 
     } 
    } 

    def generateQuote() { 
     Quote quote = Quote.get(params.id) 
     def f = new File(grailsApplication.mainContext.servletContext.getRealPath("/app/temp/${quote.code}.pdf")) 

     if (f.exists()) 
      f.delete() 

     f.withOutputStream { os -> 
     pdfRenderingService.render([template: '/quote/report/quote', model: [quote:this, post:session["paramsReport"], pdf:true]], os) 
     } 
    } 

此解決方案由wanderson-santos(https://stackoverflow.com/users/128857/wanderson-santos)和我開發。

我希望你能理解解決方案的總體思路。我明白,第一種觀點可能會有點複雜。無論如何,這是一種解決方案,允許這種需求的靈活性(即允許用戶在生成PDF之前自定義報告)。

+0

這種解決方案是否可用作Grails項目中的插件或庫?我可以在哪裏測試它? – FrancescoDS

+0

@FrancescoDS,這個解決方案不是作爲插件實現的。我可以嘗試做的是做一個例子,並在Github上分享,但是,我不能承諾這些日子,我現在很忙。 – cantoni

+0

好吧,別擔心...當我在Github上創建它時,請告訴我...感謝您的幫助! – FrancescoDS

相關問題