Template to generate html
Add Maven dependencies
Add the following dependencies to the file:
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
Create a Freemarker template
Create a new HTML file, for example, and write an HTML template in it, including the header, content and tail of the table. For details, please refer to the following example:
<table border="1"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <#list users as user> <tr> <td>${}</td> <td>${}</td> <td>${}</td> </tr> </#list> </tbody> </table>
The above template uses Freemarker's instruction syntax to achieve dynamic generation of table content, including using the <#list> tag to traverse the user list and using the ${} syntax to output user information.
Create Controller method
Write a method in Controller to get the user list, then render the above template and return the HTML content. The sample code is as follows:
@Controller public class UserController { @GetMapping("/users") public String userList(Model model) { List<User> users = new ArrayList<>(); (new User(1, "Tom", 18)); (new User(2, "Jerry", 20)); (new User(3, "John", 22)); ("users", users); return "table"; } }
The above method uses the @GetMapping annotation to process the request, then create a list of users and add it to the model. Finally, the table string is returned, representing the HTML template file to be used.
Run the project
Run the Spring Boot application and use your browser to visit http://localhost:8080/users to see the dynamically generated HTML table.
Note: The above examples are for reference only. In actual applications, you need to modify and expand according to your own needs.
2. Use iText to convert the generated HTML into PDF file
After understanding the steps of freemarker to generate html, you can use iText to generate html PDF files.
1. Write conversion code
Add Maven dependencies
Add the following dependencies to the file:
<dependency> <groupId></groupId> <artifactId>xmlworker</artifactId> <version>5.5.1</version> </dependency> <dependency> <groupId></groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <!-- supportcssStyle rendering --> <dependency> <groupId></groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.0.9</version> </dependency>
2. Write conversion code
Create a Service or Controller class in the SpringBoot application, and then write HTML to PDF code.
Method to convert freeMarker to html:
public class HtmlGenerator { public static String generate(String template, Map<String, Object> variables) throws IOException, TemplateException, IOException { Configuration config = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); // Specify the location of the FreeMarker template file (, "/filePath"); //Read the template file address ("UTF-8"); //Get template file Template tp = (template); StringWriter stringWriter = new StringWriter(); BufferedWriter writer = new BufferedWriter(stringWriter); ("UTF-8"); //Write map data into (variables, writer); String htmlStr = (); (); (); return htmlStr; } }
/filePath is the relative path of the ftl file in the project.
How to generate PDF in html:
public class PdfDocumentGenerator { private static final Logger logger = (); /** * Output a pdf to the specified outputstream * * @param htmlStr * the htmlstr * @param out * the specified outputstream * @throws Exception */ public static void generate(String htmlStr, OutputStream out) throws Exception { DocumentBuilderFactory df = (); (XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliant (XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliant DocumentBuilder builder = (); org. doc = (new ByteArrayInputStream(htmlStr .getBytes())); ITextRenderer renderer = new ITextRenderer(); (doc, null); (); (out); (); } public static void generatePlus(String htmlStr, OutputStream out) throws IOException, DocumentException { final String charsetName = "UTF-8"; Document document = new Document(PageSize.A4, 30, 30, 30, 30); (30, 30, 30, 30); PdfWriter writer = (document, out); (); // html content analysis HtmlPipelineContext htmlContext = new HtmlPipelineContext( new CssAppliersImpl(new XMLWorkerFontProvider() { @Override public Font getFont(String fontname, String encoding, float size, final int style) { if (fontname == null) { fontname = getChineseFont(); } return (fontname, encoding, size, style); } })) { @Override public HtmlPipelineContext clone() throws CloneNotSupportedException { HtmlPipelineContext context = (); try { ImageProvider imageProvider = (); (imageProvider); } catch (NoImageProviderException e) { } return context; } }; // Picture analysis (new AbstractImageProvider() { String rootPath = ("/").getPath(); @Override public String getImageRootPath() { return rootPath; } @Override public Image retrieve(String src) { if ((src)) { return null; } try { Image image = (new File(rootPath, src).toURI().toString()); // The image display location (400, 400); if (image != null) { store(src, image); return image; } } catch (Throwable e) { (); } return (src); } }); (true).autoBookmark(true).setTagFactory(()); // css analysis CSSResolver cssResolver = ().getDefaultCssResolver(true); (new FileRetrieve() { @Override public void processFromStream(InputStream in, ReadingProcessor processor) throws IOException { try ( InputStreamReader reader = new InputStreamReader(in, charsetName)) { int i = -1; while (-1 != (i = ())) { (i); } } catch (Throwable e) { } } // parse href @Override public void processFromHref(String href, ReadingProcessor processor) throws IOException { InputStream is = ("/" + href); try (InputStreamReader reader = new InputStreamReader(is,charsetName)) { int i = -1; while (-1 != (i = ())) { (i); } } catch (Throwable e) { (); } } }); HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)); Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline); XMLWorker worker = null; worker = new XMLWorker(pipeline, true); XMLParser parser = new XMLParser(true, worker, (charsetName)); try (InputStream inputStream = new ByteArrayInputStream(())) { (inputStream, (charsetName)); } (); } /** * Get the Chinese font location * @return */ public static String getChineseFont() { String chineseFont = null; chineseFont = ("/").getPath() + "font/"; if(!new File(chineseFont).exists()){ throw new RuntimeException("The font file does not exist!"+chineseFont); } return chineseFont; } }
Run the test method:
public class Pdfdest { public static void main(String[] args) throws Exception { String outputFile = "d:/"; Map<String, Object> map = new HashMap<>(); ("XXX", "test"); //Generate tool, the following code is String htmlStr = ("", map); //Generate tool, the following code is OutputStream out = new FileOutputStream(outputFile); (htmlStr,out); } }
Prepare one to put it under resource/filePath. Of course, it is best to put the font under resource/font, which needs to be used during runtime.
The code is as follows:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"></meta> <style> @page { @top-center { content: element(header) } } @page { @bottom-center { content: element(footer) } } .apply { margin: 0 auto; padding: 0 30px; } .title { margin-top: 40px ; text-align: center; font-weight: bold; //The font needs to correspond to the background font-family: SimSun; font-weight: bold; font-size: 20px; color: #333333; letter-spacing: 0; } .table { border-collapse: collapse; width: 100%; margin-top: 30px; font-family: SimSun; font-size: 14px; color: #111111; letter-spacing: 0.54px; } .label { background-color: #E6E6E6; width: 20%; } .normaltd { padding: 10px 0; } .maxtd { height: 250px; } .value { width: 30%; padding-left: 10px; } .apply { margin: 0 auto; padding: 0 30px; } .title { margin-top: 40px ; text-align: center; font-weight: bold; //The font needs to correspond to the background font-family: SimSun; font-weight: bold; font-size: 20px; color: #333333; letter-spacing: 0; } .table { width: 100%; margin-top: 30px; font-family: SimSun; font-size: 14px; color: #111111; letter-spacing: 0.54px; } .label { background-color: #E6E6E6; width: 20%; } .normaltd { padding: 10px 0; } .maxtd { height: 250px; } .value { width: 30%; padding-left: 10px; } tr { page-break-inside: avoid; page-break-after: auto; } </style> </head> <body style="font-family: SimSun"> <div class="apply"> <p class="title">Application form</p> <table border="1" cellspacing="0" class="table"> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">XXX</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr > <td valign="middle" colspan="1" class="label maxtd" align="center">XXX</td> <td valign="middle" colspan="3" class="maxtd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">XXX</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr > <td valign="middle" colspan="1" class="label maxtd" align="center">XXX</td> <td valign="middle" colspan="3" class="maxtd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td colspan="1" class="label normaltd" align="center">XXX</td> <td colspan="3" class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">XXX</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> <tr> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> <td class="label normaltd" align="center">XXX</td> <td class="normaltd value">${XXX}</td> </tr> </table> </div> </body> </html>
After executing, you can see the generated pdf file, with the file path at d:/.
This is the article about Java using freemarker template to generate html and then converting it to PDF. For more related Java freemarker to generate html content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!