Requirements describe

Recently, there is a requirement for exporting PDF files in the project. Since I have never made this requirement before, it took me a long time to find relevant materials from the Internet. Finally, aspose. Words + Freemarker is used to solve the problem, make freemarker template, and turn freemarker template into Word file. Then use aspose. Words to convert the Word file into a PDF file. At the beginning, I also tried to use Docx4J to convert Word files into PDF, but I didn’t use it after the text was translated into Chinese garbled and there were other formatting problems.

The required depend on

Since Aspose. Words is a cracked version and cannot be downloaded in the Internet warehouse, it is necessary to manually introduce the JAR package into the local library. If the company has a private server, it can also upload it to its own private server.

MVN install: install-file-dgroupid =com.aspose -DartifactId=aspose. Words -Dversion= 15.8-dpackaging =jar - Dfile = aspose - words - 15.8.0 - jdk16. JarCopy the code
<! Freemarker template engine for defining code generation templates -->
<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.28</version>
</dependency>

<dependency>
	<groupId>com.aspose</groupId>
	<artifactId>aspose.words</artifactId>
	<version>15.8</version>
</dependency>
Copy the code

Make freemarker templates

Write the document you want in Word, save the document to XML format, change the data to ${XXX} format where you need to inject data, and remember your field name, if there is more than one data add the <#list userList as user>
tag, UserList is the key in the Map.

After you edit it, save it as an.ftl file. This is the template. You can store it in the Templates folder under the Resource in your project

Word document generation utility class

package com.cxhello.example.util;

import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.Map;

/ * * *@author cxhello
 * @date2021/4/2 * /
public class WordUtil {

    private static final String ENCODING = "UTF-8";

    /** * Generate word document *@param templateName
     * @param map
     * @return
     * @throws IOException
     */
    public static File generateWord(String templateName, Map map) throws IOException {
        Configuration configuration = getConfiguration();
        Template template = configuration.getTemplate(templateName);
        File file = createDoc(map, template);
        return file;
    }

    private static Configuration getConfiguration(a) {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setDefaultEncoding(ENCODING);
        configuration.setClassForTemplateLoading(WordUtil.class, "/templates/");
        return configuration;
    }

    private static File createDoc(Map
        dataMap, Template template) {
        String name = "sellPlan.doc";
        File f = new File(name);
        Template t = template;
        try {
            FileWriter cannot be used in this place because the encoding type needs to be specified otherwise the resulting Word document will not be opened because of unrecognized encoding
            Writer w = new OutputStreamWriter(new FileOutputStream(f), ENCODING);
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        returnf; }}Copy the code

Word conversion PDF tool class

package com.cxhello.example.util;

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLEncoder;

/ * * *@author cxhello
 * @date2021/4/2 * /
public class PdfUtil {

    private static final Logger logger = LoggerFactory.getLogger(PdfUtil.class);

    public static void covertDocToPdf(File file, String fileName, HttpServletResponse response) {
        response.setContentType("application/pdf");
        try {
            if(! isWordLicense()) { logger.error("License verification failed");
            }
            fileName = fileName + ".pdf";
            response.setHeader("Content-Disposition"."attachment; filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            FileInputStream fileInputStream = new FileInputStream(file);
            Document doc = new Document(fileInputStream);
            fileInputStream.close();
            doc.save(response.getOutputStream(), SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(file ! =null) { file.delete(); }}}public static boolean isWordLicense(a) {
        boolean result = false;
        try {
            InputStream inputStream = PdfUtil.class.getClassLoader().getResourceAsStream("license.xml");
            License license = new License();
            license.setLicense(inputStream);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        returnresult; }}Copy the code

Business class

package com.cxhello.example.controller;

import com.alibaba.fastjson.JSON;
import com.cxhello.example.entity.StandardReportData;
import com.cxhello.example.util.PdfUtil;
import com.cxhello.example.util.WordUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/ * * *@author cxhello
 * @date2021/4/2 * /
@Controller
public class ExportController {

    private static final Logger logger = LoggerFactory.getLogger(ExportController.class);

    @GetMapping("/exportPdf")
    public void exportPdf(HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        String waterName = "Test Water Plant";
        map.put("waterName", waterName);
        map.put("time"."2021-03-23");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        map.put("date", date);
        Resource resource = new ClassPathResource("test.json");
        InputStream is = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            is = resource.getInputStream();
            inputStreamReader = new InputStreamReader(is);
            bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder str = new StringBuilder();
            String s;
            while((s = bufferedReader.readLine()) ! =null) {
                str.append(s);
            }
            StandardReportData standardReportData = JSON.parseObject(str.toString(), StandardReportData.class);
            map.put("standardReportData", standardReportData);
            File file = WordUtil.generateWord("template.ftl", map);
            PdfUtil.covertDocToPdfSecond(file, waterName + "Standard report", response);
        } catch (IOException e) {
            logger.error("System error", e);
        } finally {
            try {
                is.close();
                inputStreamReader.close();
                bufferedReader.close();
            } catch (IOException e) {
                logger.error("System error", e); }}}}Copy the code

Chinese garbled characters are exported from Linux

Chinese garbled characters are displayed when word files are converted to PDF using Aspose. Word on a Linux server, but can be converted normally on a Windows server. After data analysis, it is confirmed that the Linux server lacks the corresponding character library, which leads to the occurrence of garbled characters in file conversion.

Install the font library, copy all files in the C:\Windows\fonts directory on the Windows machine to the font installation directory on the production server, and then run the following command to update the font cache.

View all current fonts on Linux
fc-list
View all current Chinese fonts on Linux
fc-list :lang=zh
# copy to font directory under Linux
mkdir /usr/share/fonts/windows
cp /local/src/fonts/* /usr/share/fonts/windows
Execute install font command
cd /usr/share/fonts
sudo mkfontscale
sudo mkfontdir 
sudo fc-cache -fv
Execute the command to make the font work
source /etc/profile
If the installation fails, consider changing font permissions
chmod 755 *.ttf
Copy the code

hole

If your project is deployed with Docker, be sure to copy the required fonts to /usr/share/fonts in the Docker container. I installed Chinese fonts on the Linux physical machine, but found that the export is still Chinese garble, I am still trying to find the problem, I think it is the physical machine’s problem. It turned out that my project was deployed in a Docker container. 😂 😂 😂

The code address

Github.com/cxhello/spr…

Refer to the article

Blog.csdn.net/tomcat_zhu/…

Blog.csdn.net/hunwanjie/a…

Blog.csdn.net/weixin_4472…

Cloud.tencent.com/developer/a…

www.jianshu.com/p/86716c712…

www.cnblogs.com/stsinghua/p…