< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-thymeleaf</ artifactId>
</ dependency>
< dependency>
< groupId> com.openhtmltopdf</ groupId>
< artifactId> openhtmltopdf-core</ artifactId>
< version> 1.0.0</ version>
</ dependency>
< dependency>
< groupId> com.openhtmltopdf</ groupId>
< artifactId> openhtmltopdf-pdfbox</ artifactId>
< version> 1.0.0</ version>
</ dependency>
package com. shell. common. utils. pdf ;
import com. openhtmltopdf. pdfboxout. PdfRendererBuilder ;
import org. springframework. util. ResourceUtils ;
import org. thymeleaf. context. Context ;
import org. thymeleaf. spring5. SpringTemplateEngine ;
import org. thymeleaf. templateresolver. ClassLoaderTemplateResolver ;
import java. io. OutputStream ;
import java. util. Map ;
public class PdfUtil {
public static void buildPdf ( OutputStream os, String pdfFileName, String templateName, Map < String , Object > variables) throws Exception {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver ( ) ;
resolver. setPrefix ( "templates/" ) ;
resolver. setSuffix ( ".html" ) ;
SpringTemplateEngine templateEngine = new SpringTemplateEngine ( ) ;
templateEngine. setTemplateResolver ( resolver) ;
Context context = new Context ( ) ;
context. setVariable ( "templateName" , templateName) ;
context. setVariable ( "pdfFileName" , pdfFileName) ;
context. setVariables ( variables) ;
String example = templateEngine. process ( templateName, context) ;
PdfRendererBuilder builder = new PdfRendererBuilder ( ) ;
builder. useFont ( ResourceUtils . getFile ( "classpath:templates/fonts/simsun.ttf" ) , "simsun" ) ;
builder. useFastMode ( ) ;
builder. withHtmlContent ( example, ResourceUtils . getURL ( "classpath:templates/img/" ) . toString ( ) ) ;
builder. toStream ( os) ;
builder. run ( ) ;
}
}
package com. step. pdf. demo. controller ;
import com. step. pdf. demo. util. PdfUtil ;
import org. springframework. web. bind. annotation. GetMapping ;
import org. springframework. web. bind. annotation. RestController ;
import javax. servlet. http. HttpServletResponse ;
import java. util. Arrays ;
import java. util. HashMap ;
import java. util. Map ;
@RestController
public class DemoController {
@GetMapping ( "pdf" )
public void test ( HttpServletResponse response) throws Exception {
Map < String , Object > variables = new HashMap < > ( ) ;
variables. put ( "assessmentTypeName" , "测试" ) ;
variables. put ( "staffName" , "staffName" ) ;
variables. put ( "functions" , "functions" ) ;
variables. put ( "assessmentDate" , "assessmentDate" ) ;
variables. put ( "roles" , "roles" ) ;
variables. put ( "score" , "score" ) ;
variables. put ( "signature" , "signature" ) ;
PdfUtil . buildPdf ( response, "用于测试的pdf" , "parent" , variables) ;
}
}
<! DOCTYPE html >
< html xmlns: th= " http://www.thymeleaf.org" lang = " en" >
< head>
< meta charset = " UTF-8" />
< title th: text= " ${pdfFileName}" > </ title>
< style>
@page {
size : A4;
@top-center {
content : element ( header) ;
}
@bottom-center {
font-family : 'simsun' , serif;
}
}
html,
body {
font-family : 'simsun' , serif;
font-size : 14px;
}
table {
-fs-table-paginate : paginate;
border-collapse : collapse;
width : 100%;
}
.headingBox {
font-size : 18px;
text-align : center;
font-style : italic;
font-weight : bolder;
}
table,
td,
th {
border : 0px solid #555;
padding : 3px 5px;
}
.box1,
.box2,
.box3 {
padding : 10px 20px;
border-top : 1px solid #999;
}
.trBox {
display : flex;
}
.tdBox {
width : 50%;
display : flex;
}
.titleBox {
display : inline-block;
width : 32%;
font-weight : bold;
}
.contentBox {
width : 68%;
color : cornflowerblue;
}
.titleOverviewBox {
display : inline-block;
width : 64%;
font-weight : bold;
}
.contentOverViewBox {
width : 36%;
color : cornflowerblue;
}
.functionTitleBox,
.commentsTitleBox {
font-style : italic;
font-weight : bolder;
margin : 0 0 0 2%;
}
</ style>
< style>
#app {
border : 1px solid #999;
width : 550px;
box-sizing : border-box;
margin : 0px auto;
}
#comm {
height : 100px;
}
#content {
white-space : pre-line;
}
</ style>
</ head>
< body>
< div id = " app" >
< h3 th: text= " ' Competence Assessment_' +${assessmentTypeName}" class = " headingBox" > </ h3>
< div class = " box1" >
< table border = " 0px;" class = " baseInfoBox" >
< tr class = " trBox" >
< td class = " tdBox" > < span class = " titleBox" > Name:</ span> < span class = " contentBox" th: text= " ${staffName}" > </ span> </ td>
< td class = " tdBox" > </ td>
</ tr>
< tr class = " trBox" >
< td class = " tdBox" > < span class = " titleBox" > Function:</ span> < span class = " contentBox" th: text= " ${functions}" > </ span> </ td>
< td class = " tdBox" > < span class = " titleOverviewBox" > Date:</ span> < span class = " contentOverViewBox"
th: text= " ${assessmentDate}" > </ span> </ td>
</ tr>
< tr class = " trBox" >
< td class = " tdBox" > < span class = " titleBox" > Role:</ span> < span class = " contentBox" th: text= " ${roles}" > </ span> </ td>
< td class = " tdBox" > < span class = " titleOverviewBox" > Agreegate Source:</ span>
< span class = " contentOverViewBox" th: text= " ${agreegateSource}" > </ span> </ td>
</ tr>
</ table>
</ div>
< div th: each= " item:${questionList}" >
< div class = " box1" >
< h4 class = " functionTitleBox" th: text= " ${item.functionName}+' :' " > </ h4>
< div class = " w" >
< tbody th: border= " 0" >
< tr>
< td th: text= " ${item.questionContent}" id = " content" > </ td>
</ tr>
</ tbody>
</ div>
</ div>
< div class = " box1" >
< h4 class = " commentsTitleBox" > Comments:</ h4>
< div class = " c" th: height= " 500px" id = " comm" >
</ div>
< div style = " display : flex; " >
< div style = " padding-left : 18em" >
< span th: text= " ' Score: ' " > </ span> < span
th: text= " ' Signature:' " > </ span> </ div>
</ div>
</ div>
</ div>
</ div>
</ body>
</ html>