在我的Grails項目中,我使用PDF插件從gsp頁面生成PDF。如何爲grails創建PDF編輯器
它運行良好,但我想向用戶添加更多的功能,所以我想讓用戶編輯PDF基本模板(在gsp頁面中定義),特別是我想允許編輯模板內的文本並將其存儲在某處。
有人知道該怎麼辦?
在我的Grails項目中,我使用PDF插件從gsp頁面生成PDF。如何爲grails創建PDF編輯器
它運行良好,但我想向用戶添加更多的功能,所以我想讓用戶編輯PDF基本模板(在gsp頁面中定義),特別是我想允許編輯模板內的文本並將其存儲在某處。
有人知道該怎麼辦?
如果您只想更改文本,可以將編輯後的文本與用戶標識一起存儲到數據庫中,並將其加載到gsp頁面而不是標準文本中。
如果您還想更改頁面的樣式,您可以嘗試將整個gsp頁面存儲在數據庫中,並讓用戶使用HTML編輯器進行編輯。
這就是我如何與,也許有人有一個更好的主意
的PDF插件的底層組件並沒有嚴格要求.gsp文件開始。它只是使用作爲字符串呈現的.gsps,並將它們提供給flyingsaucer lib。因此,您可以使用所見即所得類型編輯器來允許用戶創建html片段,以某種方式保存這些字符串,然後將它們自己提供給flyingsaucer庫。只需查看插件的包含服務方法即可。這聽起來很可怕,但它確實不是很複雜。
你可能想用自己的HTML標記來包裝用戶生成的內容,以達到理智和樣式的目的,但是你想要的想法是完全可行的。
您認爲String是包含所有gsp頁面的好類型嗎? – FrancescoDS
當然,String是可以的,但是您可能想要將它映射到數據庫級別的varchar以外的內容。在您的域中添加一個映射塊,如:'static mapping = {gspContent type:'text'}' – aeischeid
您可以擁有一種具有兩種不同方式的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之前自定義報告)。
這種解決方案是否可用作Grails項目中的插件或庫?我可以在哪裏測試它? – FrancescoDS
@FrancescoDS,這個解決方案不是作爲插件實現的。我可以嘗試做的是做一個例子,並在Github上分享,但是,我不能承諾這些日子,我現在很忙。 – cantoni
好吧,別擔心...當我在Github上創建它時,請告訴我...感謝您的幫助! – FrancescoDS
你知道一些易於使用的HTML編輯器嗎?可以將它集成到Grails的某些gsp頁面中嗎? – FrancescoDS