Wiki source code of Sheet

Version 1.1 by superadmin on 2025/05/22 17:45

Hide last authors
superadmin 1.1 1 {{velocity output="false"}}
2 #set ($sheetReference = 'XWiki.PDFExport.Sheet')
3 #set ($pdfElements = ['cover', 'toc', 'header', 'footer'])
4 #set ($pdfExportJobId = $request.jobId.split('/'))
5 #if ($pdfExportJobId)
6 #set ($pdfExportJobStatus = $services.job.getJobStatus($pdfExportJobId))
7 #set ($pdfExportJobRequest = $pdfExportJobStatus.request)
8 #else
9 #set ($pdfExportJobStatus = $NULL)
10 #set ($pdfExportJobRequest = $NULL)
11 #end
12
13 #macro (getPDFExportConfigFromRequest $pdfExportConfig)
14 #if ($pdfExportJobRequest)
15 #set ($discard = $pdfExportConfig.putAll({
16 'template': $pdfExportJobRequest.template,
17 'cover': $pdfExportJobRequest.isWithCover(),
18 'toc': $pdfExportJobRequest.isWithToc(),
19 'header': $pdfExportJobRequest.isWithHeader(),
20 'footer': $pdfExportJobRequest.isWithFooter()
21 }))
22 #end
23 #end
24
25 #macro (renderPDFSheet $pdfExportConfig)
26 #set ($discard = $response.setContentType('text/html'))
27 #set ($discard = $xwiki.ssx.use($sheetReference))
28 ## Temporarily disable the JavaScript minification until we find a way to fix the following Closure Compiler error:
29 ## [JSC_DYNAMIC_IMPORT_USAGE] Dynamic import expressions cannot be transpiled.
30 ## See https://github.com/google/closure-compiler/wiki/JS-Modules#dynamic-import-expressions
31 ## See also https://github.com/google/closure-compiler/issues/2770 ([FEATURE] Support dynamic import)
32 ## This error is unexpected considering that we disable the transpiling here
33 ## https://github.com/xwiki/xwiki-platform/blob/xwiki-platform-15.7/xwiki-platform-core/xwiki-platform-skin/xwiki-platform-skin-skinx/src/main/java/com/xpn/xwiki/web/sx/JsExtension.java#L91-L97
34 ## We're using STABLE as input ECMAScript version, see https://github.com/xwiki/xwiki-commons/blob/xwiki-commons-15.7/pom.xml#L2585
35 ## which is probably lower than ECMAScript 2020 (ES11) when support for dynamic imports was introduced.
36 ## See also https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
37 ## and https://caniuse.com/?search=import()
38 #set ($discard = $xwiki.jsx.use($sheetReference, {'minify': false, 'defer': false}))
39 #set ($discard = $xwiki.ssx.use($pdfExportConfig.template))
40 #set ($discard = $xwiki.jsx.use($pdfExportConfig.template))
41 ## Use the specified PDF file name as the title of the HTML page in order to have it suggested as file name when
42 ## saving the PDF from the browser's Print Preview dialog.
43 #if ($pdfExportJobRequest)
44 #set ($title = $pdfExportJobRequest.fileName)
45 #end
46 ## Output the HTML header but without the garbage from the start of the BODY tag.
47 #set ($htmlHeader = "#template('htmlheader.vm')")
48 ## The PDF export doesn't target only the paper paged media, and we want to preserve the styles from the XWiki skin as
49 ## much as possible.
50 #set ($htmlHeader = $htmlHeader.replace('data-xwiki-paged-media="paper"', ''))
51 #set ($headTagEnd = $htmlHeader.indexOf('</head>'))
52 #set ($bodyTagStart = $htmlHeader.indexOf('<body'))
53 #set ($bodyContentStart = $htmlHeader.indexOf('>', $bodyTagStart) + 1)
54 $htmlHeader.substring(0, $headTagEnd)
55 <script>
56 requirejs.config({
57 ## When performing large multi-page exports the RequireJS timeout can be reached because there are many HTTP
58 ## requests and the browser uses a limited pool to handle them. We noticed this problem on a PDF export with many
59 ## live tables because they fetch their results pretty early, before many RequireJS modules are requested. In any
60 ## case, we have the page ready timeout to stop the export in case it takes too much time to load the print preview
61 ## page. We don't need another timeout for RequrieJS modules.
62 waitSeconds: 0,
63 ## PagedJS uses some utility functions that are not exposed by the RequireJS module, so we have to import them
64 ## ourselves from the WebJar in order to be able to patch PagedJS bugs.
65 config: {
66 'pagedjs-module': {
67 baseURL: $jsontool.serialize($services.webjars.url('org.webjars.npm:pagedjs', ''))
68 }
69 }
70 });
71 </script>
72 ## Inject the required skin extensions.
73 $!pdfExportJobStatus.requiredSkinExtensions
74 #clientSidePDFExportConfiguration()
75 ## Start the BODY tag.
76 $htmlHeader.substring($headTagEnd, $bodyContentStart)
77 #set ($pdfTemplateObj = $xwiki.getDocument($pdfExportConfig.template).getObject('XWiki.PDFExport.TemplateClass'))
78 #foreach ($element in $pdfElements)
79 #if ($pdfExportConfig.get($element))
80 #set ($output = "#renderPDFElement($pdfTemplateObj $element)")
81 #set ($output = $output.trim())
82 #if ($output != '')
83 <div class="pdf-$element">$output</div>
84 #end
85 #end
86 #end
87 <div id="xwikicontent">
88 #renderPDFContent()
89 </div>
90 ## Close the tags opened in htmlheader.vm
91 </body>
92 </html>
93 #end
94
95 #macro (clientSidePDFExportConfiguration)
96 #set ($clientSideConfig = {
97 'documents': [],
98 'baseURL': $pdfExportJobRequest.baseURL
99 })
100 #foreach ($renderingResult in $pdfExportJobStatus.documentRenderingResults)
101 #set ($discard = $clientSideConfig.documents.add({
102 'reference': $services.model.serialize($renderingResult.documentReference, 'default'),
103 'idMap': $renderingResult.idMap
104 }))
105 #end
106 <script id="pdfExportConfig" type="application/json">$jsontool.serialize($clientSideConfig).replace(
107 '<', '\u003C')</script>
108 #end
109
110 #macro (renderPDFElement $pdfTemplateObj $element)
111 #unwrapXPropertyDisplay($tdoc.display($element, $pdfTemplateObj))
112 #end
113
114 #macro (renderPDFContent)
115 #if (!$pdfExportJobRequest.isWithTitle())
116 ## The document renderer includes the document metadata in the rendering results only when document titles are
117 ## displayed (because we should have a single metadata on a print page and the document title starts on a new print
118 ## page, but also because the metadata can be used to tweak how the document title is displayed, e.g. to skip or
119 ## reset heading numbering). We may still want to display the metadata for a single page export or for a multipage
120 ## export without titles, but in this case the same metadata is going to be displayed on all print pages, and it
121 ## comes from the target document on which the PDF export was triggered.
122 #outputMetadataFromTargetDocument()
123 #end
124 #foreach ($renderingResult in $pdfExportJobStatus.documentRenderingResults)
125 $renderingResult.getHTML()
126 #end
127 #end
128
129 #macro (outputMetadataFromTargetDocument)
130 #set ($metadata = {
131 'class': 'hidden',
132 'data-xwiki-document-reference': $services.model.serialize($doc.documentReference, 'default')
133 })
134 #set ($discard = $tdoc.display('metadata', $pdfTemplateObj))
135 <h1#foreach ($entry in $metadata.entrySet()) $escapetool.xml($entry.key)="$escapetool.xml($entry.value)"#end
136 >$escapetool.xml($tdoc.plainTitle)</h1>
137 #end
138 {{/velocity}}
139
140 {{velocity wiki="false"}}
141 #if ($request.sheet == $sheetReference)
142 ## Default PDF Export configuration.
143 #set ($pdfExportConfig = {
144 'template': 'XWiki.PDFExport.Template',
145 'cover': true,
146 'toc': true,
147 'header': true,
148 'footer': true
149 })
150 #getPDFExportConfigFromRequest($pdfExportConfig)
151 #renderPDFSheet($pdfExportConfig)
152 #end
153 {{/velocity}}