根据word模板导出pdf

根据word模板导出pdf

前两天接到一个需求,根据word模板导出pdf。

详细需求

依据模板替换相关参数之后,怕生成的word下载后被别人再改,故要求转成pdf。由于下载的文件较多,故需要在生成pdf之后再压缩成一个zip包,提供给用户下载。

实现思路:

  1. 将doc模板替换成最终结果word;
  2. 将最终结果word,转换为pdf,输出到某个目录中;
  3. 将pdf所在目录,打包成zip文件;

将doc模板替换成最终结果word

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.17</version>
		</dependency>
		<dependency>
			<groupId>com.deepoove</groupId>
			<artifactId>poi-tl</artifactId>
			<version>1.5.1</version>
		</dependency>

网上找到了poi-tl,地址:http://deepoove.com/poi-tl/,实验了一波,完美替换模板中的变量。

将最终结果word,转换为pdf

这儿我网上找了好多个方法,有的转换支持不太好,有的依赖过重,有的只支持Windows。(具体有哪些方法,这个可以随时网上查询下)最终选择了使用aspose-words-16.8.0-jdk16.jar(这个包是个非开源的,网上找的。如果有侵犯到相关利益,可随时联系我,删除此博客。)
使用这个包,转换基本没问题,但是将东西打包至Linux中运行时,显示pdf为乱码。原因是,这个包中依赖的Windows中默认的字体,这些字体在Linux中没有所导致的。所以,需要将Windows中的字体安装到Linux中。

将Windows中的字体安装到Linux中

依据这篇博客操作 https://blog.csdn.net/huangpeigui/article/details/90900443
大概操作:

  1. 安装字体库,之后在/usr/share目录就可以看到fonts和fontconfig目录了(之前是没有的)
yum -y install fontconfig
  1. 在/usr/share/fonts下新建一个chinese目录
  2. 将C:\Windows\Fonts目录中的字体,上传至Linux刚才新建的chinese目录中
  3. 修改Chinese目录的权限
chmod -R 755 /usr/share/fonts/chinese
  1. 安装ttmkfdir来搜索目录中所有的字体信息
yum -y install ttmkfdir
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
  1. 修改字体配置文件
vi /etc/fonts/fonts.conf

将中文字体位置加进去

<!-- Font directory list -->

        <dir>/usr/share/fonts</dir>
        <dir>/usr/share/X11/fonts/Type1</dir> <dir>/usr/share/X11/fonts/TTF</dir> <dir>/usr/local/share/fonts</dir>
        <dir>/usr/share/fonts/chinese</dir><!--这句是我加的 -->
        <dir prefix="xdg">fonts</dir>
        <!-- the following element will be removed in the future -->
        <dir>~/.fonts</dir>
  1. 刷新内存中字体
 fc-cache

将文件夹打包成zip

hutool-all这个工具挺好用的,囊括了常用的utils。

		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.1.0</version>
		</dependency>

优化

  1. 由于要导出的文件较多,所以考虑用多线程实现,来提高生成速度。
  2. 模板文件可以缓存起来,下次用时可以不用再去盘里面读取。
  3. 中间生成的最终版word可以不持久化到盘中,直接在内存中转成pdf。

demo代码实现

WordTemplate2PdfZip

package com.hdj.test.poi;

import java.io.File;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.aspose.words.License;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;

/**
 * Hello world!
 *
 */
public class WordTemplate2PdfZip {
	
	public static void main(String[] args) throws Exception {
		String prePath = "/root/";
		getLicense();
		String template = prePath+"template_02.docx";
		byte[] readBytes = FileUtil.readBytes(template);

		ExecutorService fixedExecutorService = Executors.newFixedThreadPool(8);
		long start = System.currentTimeMillis();

		for (int i = 0; i < 2; i++) {
			Task task = new Task(i, readBytes, start, prePath);
			fixedExecutorService.execute(task);
		}
		
		fixedExecutorService.shutdown();
		boolean isFlag=true;
        while (isFlag){
            if (fixedExecutorService.isTerminated()){
                isFlag=false;
                ZipUtil.zip(new File(prePath+"a"));
                System.out.println("总共用时:" + (System.currentTimeMillis() - start));
            }
        }
		
	}

	public static boolean getLicense() {
		boolean result = false;
		try {
			InputStream license = App2.class.getClassLoader().getResourceAsStream("license.xml");
			License aposeLic = new License();
			aposeLic.setLicense(license);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}

Task

package com.hdj.test.poi;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.HashMap;

import org.apache.commons.io.output.ByteArrayOutputStream;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;

public class Task implements Runnable {
	private int num;
	private byte[] bytes;
	private long start;
	private String prePath;

	public Task(int num, byte[] readBytes, long start, String prePath) {
		this.num = num;
		this.bytes = readBytes;
		this.start = start;
		this.prePath = prePath;
	}

	@Override
	public void run() {
		System.out.println("正在执行任务  " + num);
		try {

//			String outDocFile = prePath+"a/out_template{0}.docx";
			String pdfFile = prePath+"a/out_template{0}.pdf";

//			String thisOutDocFile = MessageFormat.format(outDocFile, String.valueOf(num));
			InputStream inputStream = new ByteArrayInputStream(this.bytes);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			XWPFTemplate.compile(inputStream).render(new HashMap<String, Object>() {
				private static final long serialVersionUID = 1L;

				{
					put("name", "张三");
					put("sex", "男");
				}
			})
			.write(out);
//			.writeToFile(thisOutDocFile);

			
//			FileInputStream thisOutDocFileInputStream = new FileInputStream(thisOutDocFile);// 待处理的文件
			InputStream thisOutDocFileInputStream = new ByteArrayInputStream(out.toByteArray());
			Document doc = new Document(thisOutDocFileInputStream);
			File outputFile = new File(MessageFormat.format(pdfFile, String.valueOf(num)));// 输出路径
			FileOutputStream fileOS = new FileOutputStream(outputFile);

			doc.save(fileOS, SaveFormat.PDF);
			inputStream.close();
			out.close();
			thisOutDocFileInputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("线程" + num + "执行完毕,用时:"+ (System.currentTimeMillis() - start));
	}
}

license.xml

<License>
  <Data>
    <Products>
      <Product>Aspose.Total for Java</Product>
      <Product>Aspose.Words for Java</Product>
    </Products>
    <EditionType>Enterprise</EditionType>
    <SubscriptionExpiry>20991231</SubscriptionExpiry>
    <LicenseExpiry>20991231</LicenseExpiry>
    <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
  </Data>
  <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

pom中所有依赖

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.17</version>
		</dependency>
		<dependency>
			<groupId>com.deepoove</groupId>
			<artifactId>poi-tl</artifactId>
			<version>1.5.1</version>
		</dependency>
		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.1.0</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>

aspose-words-16.8.0-jdk16.jar下载

链接: https://pan.baidu.com/s/1TK2GaOXa9ButHeeKouQBBA 提取码: cdgk

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值