java处理word插入数据转PDF及下载PDF

欢迎使用Markdown编辑器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

因公司需求,需将客户电子签名合成在责任书,并转成PDF文档存档,后期可下载PDF文件,所以操作了word合并文字图片,转PDF,下载PDF;


提示:以下是本篇文章正文内容,下面案例可供参考

一、引入jar包

	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-resources-plugin</artifactId>
		<version>3.1.0</version>
		<configuration>
			<nonFilteredFileExtensions>
			<!--这个是为了避免操作docx文档时出错-->
				<nonFilteredFileExtension>docx</nonFilteredFileExtension>
			</nonFilteredFileExtensions>
		</configuration>
	</plugin>
	<!--这个是为了下载e-iceblue的jar包-->
	<repositories>
		<repository>
			<id>com.e-iceblue</id>
			<name>e-iceblue</name>
			<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
		</repository>
	</repositories>
	<dependency>
		<groupId> e-iceblue </groupId>
		<artifactId>spire.doc.free</artifactId>
		<!--注意这里的版本,之前使用的4.1.0文件头会有一串提示-->
		<version>3.9.0</version>
	</dependency>
	<dependency>
		<groupId>com.deepoove</groupId>
		<artifactId>poi-tl</artifactId>
		<version>1.10.0</version>
	</dependency>
	<dependency>
		<groupId>fr.opensagres.xdocreport</groupId>
		<artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>
		<version>2.0.1</version>
	</dependency>
	<dependency>
		<groupId>cn.afterturn</groupId>
		<artifactId>easypoi-base</artifactId>
		<version>4.1.0</version>
	</dependency>
	<dependency>
		<groupId>cn.afterturn</groupId>
		<artifactId>easypoi-web</artifactId>
		<version>4.1.0</version>
	</dependency>
	<dependency>
		<groupId>cn.afterturn</groupId>
		<artifactId>easypoi-annotation</artifactId>
		<version>4.1.0</version>
	</dependency>

二、使用步骤

1.前端上传电子签名图片

这一步公司里是用的C端操作的所以没有代码示例,但是操作其实也很简单的就是按前端上传文件的格式调用dfs文件服务接口上传,返回上传地址:类似e9c37ab8f83d4cada7f73cf3c9d877e0这样的;然后走完业务流程保存本次操作,将e9c37ab8f83d4cada7f73cf3c9d877e0随其他参数一起传送给java后端;后端根据这个地址下载电子签名图片并插入word模板中;这里电子签名的上传下载就不作详细说明了;

2.java下载电子签名图片并插入word再转PDF后上传

先看看我们的word模板设置
在这里插入图片描述
这里需要将卡号、电子签名图片、签字年月日填入对应的文档;
1、首先我们从fds服务器下载电子签名图片,此时下载的是byte数组,需要进行处理后插入word文档;
代码如下(示例):

//这里的文件下载就是FastDNS的服务下载,需要朋友们自己搭建下网上教程很多也比较简单
		byte[] bytes = fileUpDownloadService.download(fundContract.getSignatureImagePath());
		Map<String,Object> map = new HashMap<>();
		map.put("cardNo","323232323232");//卡号对应的值
		map.put("year","2022");//年
		map.put("month","07");//月
		map.put("day","15");//日
		//大家注意此处没有处理图片,是把图片的设置值放在了工具类处理的
		fastDFSUtil.getFileByBytes(bytes, UuidUtils.generateUuid(),map);

2、下面是工具类的示例代码,只是做demo所以没有怎么整理

package com.jy.util;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.jy.service.IFileUpDownloadService;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Map;

/**
 * @Author jy
 * @Date 2022/7/5 15:21
 * @Version 1.0
 */
@Component
public class FastDFSUtil {
    @Autowired
    private IFileUpDownloadService fileUpDownloadService;
    /**
     *
     * @param bytes
     * @param fileName
     * @param map
     */
    public void getFileByBytes(byte[] bytes, String fileName, Map<String, Object> map) {
        String rootPath = System.getProperty("user.dir");
        String filePath = rootPath+"\\card\\src\\main\\resources\\templates\\images";
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file;
        Document document = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {// 判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + "\\" + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
            map.put("image", Pictures.ofStream(new FileInputStream(filePath + "\\"+fileName), PictureType.PNG)
                        .size(50, 25).create());
            XWPFTemplate template = XWPFTemplate.compile(filePath+"\\test.docx").render(map);
            template.write(new FileOutputStream(filePath+"\\test11.docx"));
            //保存为PDF格式
            document = new Document();
            document.loadFromFile(filePath+"\\test11.docx");
            //保存结果文件
            document.saveToFile(filePath + "\\test11.pdf", FileFormat.PDF);
            //上传文件
            File pdf = new File(filePath + "\\test11.pdf");
            MultipartFile multipartFile = new MockMultipartFile(pdf.getName(), pdf.getName(),
                    null, new FileInputStream(pdf));
            String upload = fileUpDownloadService.upload(multipartFile);
            //这里打印出上传后返回的保存地址,待会复制出来下载的时候使用
            System.out.println(upload);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (document !=null){
                document.close();
            }
        }
    }
    /**
     根据byte数组,生成文件
     **/
    public static void getFile(byte[] bfile, String filePath,String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath+"\\"+fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    /**
     * * 输出指定文件的byte数组
     * @param filePath 文件路径
     * @param os 输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException{
        FileInputStream fis = null;
        try{
            File file = new File(filePath);
            if (!file.exists()){
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0){
                os.write(b, 0, length);
            }
        }catch (IOException e){
            throw e;
        }finally{
            if (os != null){
                try{
                    os.close();
                } catch (IOException e1){
                    e1.printStackTrace();
                }
            }
            if (fis != null){
                try{
                    fis.close();
                } catch (IOException e1){
                    e1.printStackTrace();
                }
            }
        }
    }
}

3、根据自己的业务需求触发请求后,我们可以得到以下文件:电子签名图片、插入数据后的word文档、转换为PDF的文档
在这里插入图片描述在这里插入图片描述
在这里插入图片描述4、至此我们就完成了整个需求的一大半,word的赋值转换,PDF的上传;接下来就是需求的另一个点,我们需要在其他列表页面下载之前上传的PDF;
在这里插入图片描述
以上是页面效果,我们需要下载这个签字版的PDF文件

3.java下载PDF

1、首先我们从fds服务器下载电子签名图片,此时下载的是byte数组,需要进行处理后插入word文档;
代码如下(示例):

	<div>
        <div class="breadcrumb">
                附件
        </div>
        <p>《市场交易管理规则》告知书 <a class="" style="color: #007BFF" href="javascript:void(0);" onclick="getPDF('1')">下载</a></p>
        <p>《市场食品质量安全责任书》&nbsp;<a class="" style="color: #007BFF" href="javascript:void(0);" onclick="getPDF('2')" >下载</a></p>
    </div>
    <script>
    	function getPDF(num) {
        var name = "";
        if (num==1){
            name = "《市场交易管理规则》告知书";
        } else {
            name = "《市场食品质量安全责任书》";
        }
        //const queryParams = generateFormCondition2Json({ num: num });
        $.ajax({
            type: "GET",
            url: "${contextPath}/contract/getImage.action?num="+num,//这里的参数是根据各自的业务需求传递
            //data: JSON.stringify(queryParams),
            headers:{"content-type":"application/json; charset=utf-8"}, //请求头类型
            //responseType: 'blob',//按这种方式PDF打开空白,改成下面这种才行,具体什么问题不清楚,找前端同事问的
           xhrFields: {
                responseType: 'arraybuffer'
            },
            success: function (ret) {
                console.log(ret)
                bui.loading.hide();
                if (ret) {
                    downloadFile(ret,name);
                } else {
                    bs4pop.alert("", {type: 'error'});
                }
            },
            error: function () {
                bui.loading.hide();
                bs4pop.alert('远程访问失败', {type: 'error'});
            	}
       	 	});
    	}
    	function downloadFile(data,name) {
        let blob = new Blob([data], { type: "application/pdf" });
        let url = window.URL.createObjectURL(blob);
        const link = document.createElement("a"); // 创建a标签
        link.href = url;
        link.download = name; // 重命名文件
        link.click();
        URL.revokeObjectURL(link.href); // 释放内存
    	}
	</script>

后端代码如下:

public void getImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		//根据之前上传时返回的地址下载文件
		byte[] bytes = fileUpDownloadService.download("ad892f8784444e599160ad9cfa373347");
        //你的文件所存放的地址
        String rootPath = System.getProperty("user.dir");
        String filePath = rootPath+"\\card\\src\\main\\resources\\templates\\images\\";
		String uuid = UUID.randomUUID().toString();
		String pdfName = uuid+".pdf";
		fastDFSUtil.getFile(bytes,filePath,pdfName);
		String pdfDownPath = filePath+pdfName;
        response.setCharacterEncoding("utf-8");
        response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(pdfDownPath.trim(), "UTF-8"));
		fastDFSUtil.writeBytes(pdfDownPath, response.getOutputStream());
        File file = new File(filePath);
        if (file.exists()) {
            DataOutputStream temps = new DataOutputStream(response.getOutputStream());
            DataInputStream in = new DataInputStream(new FileInputStream(pdfDownPath));
            byte[] b = new byte[2048];
            while ((in.read(b)) != -1) {
                temps.write(b);
                temps.flush();
            }
            in.close();
            temps.close();
        } else {
            log.error("文件不存在!");
        }
		//return bytes;
	}
点击下载后的效果即为:
![在这里插入图片描述](https://img-blog.csdnimg.cn/384dd2614f394c9193e3daa2edfca8fb.jpeg#pic_center)
# 总结
以上就是全部内容,代码写得比较乱,主要是实现功能,具体的工具类还可以再细分,以及在word填充值的入参方面还可以再处理下,对转换的文本格式,及图片大小,还有填充的内容这些都是可以扩展的;再有就是确实不擅长前端,所以只能问问同事;后端jar的引用花了一点时间处理,因为可能版本不同就会造成一些影响;给自己留一个工具类,同时也希望能给需要的你一些帮助吧!一起加油!!!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值