c jpg转nv21_文件转PDF有哪些隐藏的坑?你了解多少

各位亲爱的小伙伴们,你们好呀,我是罗少,感谢你们的支持,今天我又来跟你唠嗑了。

    程序员可能经常会要写一些文档之类的东西交付给别人,一般我们都是用word写,提供的时候是PDF格式的,因为PDF不容易被编辑篡改。我们经常就是右键保存选择保存为PDF格式(很多自带的编辑器都自带转换功能),是不是觉得很好用。那么用代码怎么来实现呢?刚好曾经做项目就有这个需求,经理让我去研究一下,找遍了资料,遇到了很多坑,搞了一个礼拜才解决。现在拿出来跟大家分享一下。

    我又要开启斗图模式了,别慌!

  1. 图片转PDF

    (1)新建一个工程maven(以上默认你会)-> 引入依赖包

com.itextpdfitextpdf5.5.5

    (2)新建一个service

     由于我们是简单的例子,没有直接从前端传输文件到后端(该步骤本文省略),直接后端用文件路径,实际项目中肯定是要从前端传入文件到后端的,后端再进行解析

package jp.service.impl;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import jp.service.IFileHandleService;
import jp.utils.ResultVoUtil;
import jp.vo.ResultVo;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;@Servicepublic class FileHandleImpl implements IFileHandleService {private static final int regular_width = 842;
private static final int regular_height = 595;
private static final int vertical_regular_width = 595;
private static final int vertical_regular_height = 842;@Overridepublic ResultVo fileToPdf() {
String imagPath = "D:/test.jpg";//图片文件存放的地址String pdfOutPath = "D:/test.pdf";//输出PDF的路径
boolean result = imgToPdf(imagPath, pdfOutPath);
if(result)ResultVoUtil.success();
return ResultVoUtil.error("0001", "转换失败");}private boolean imgToPdf(String imagPath, String pdfOutPath) {boolean changeResult = false;
try {
FileOutputStream fos = new FileOutputStream(pdfOutPath);Document doc = new Document(null, 0, 0, 0, 0);// 写入PDF文档PdfWriter.getInstance(doc, fos);// 读取图片流BufferedImage img = null;// 实例化图片Image image = null;
float newHeight = 0f, newWidth = 0f;img = ImageIO.read(new File(imagPath));Map,Float> result = setImageWidthHeight(img.getWidth(), img.getHeight(),newWidth, newHeight);newWidth = result.get("width");newHeight = result.get("height");doc.setPageSize(new Rectangle(newWidth,newHeight));image = Image.getInstance(imagPath);image.scaleAbsolute(new Rectangle(newWidth,newHeight));// 添加图片到文档doc.newPage();doc.open();doc.add(image);// 关闭文档doc.close();changeResult = true;System.out.println("图片转PDF成功");} catch (Exception e) {
System.out.println("图片转PDF失败");e.printStackTrace();}return changeResult;}/**
* 设置PDF的宽高*
* @param width* @param height* @param newWidth* @param newHeight* @return*/private Map, Float> setImageWidthHeight(float width, float height, float newWidth, float newHeight) {float res = width / height;
if (res >= 1) { //横向if (width > regular_width) {
newWidth = regular_width;newHeight = (regular_width / width) * height;} else if (height > regular_height) {
newHeight = regular_height;newWidth = (regular_height / height) * width;} else {//如果都在范围内,不做任何操作newWidth = width;newHeight = height;}
} else {if (width > vertical_regular_width) {
newWidth = vertical_regular_width;newHeight = (vertical_regular_width / width) * height;} else if (height > vertical_regular_height) {
newHeight = vertical_regular_height;newWidth = (vertical_regular_height / height) * width;} else {//如果都在范围内,不做任何操作newWidth = width;newHeight = height;}
}
Map, Float> result = new HashMap, Float>();result.put("width", newWidth);result.put("height", newHeight);
return result;}
}
package jp.service;
import jp.vo.ResultVo;
public interface IFileHandleService {
ResultVo fileToPdf();}

备注:这些图片的宽度和高度,都是前人经过大量实现的出来比较符合原图片大小的值,如果没有必要的话,可以不需要修改。默认这些就可以,如果你应该兴趣可以自行修改,然后看看效果

private static final int regular_width = 842;
private static final int regular_height = 595;
private static final int vertical_regular_width = 595;
private static final int vertical_regular_height = 842;

    我们来看一下实际效果。

我在D盘创建了一个test.jpg文件,代码设置输出结果路径为D:/test.pdf

1ad753f3f05e4b86d88d4ab128f883cc.png

点击程序运行,看一下效果

faec43ac297233b438132d30c40fe531.png

此时在D盘生成了pdf文件,同时PDF阅读器打开,可以发现他的比率和清洗都都跟原图片类似。 

2c724dc1784fe8d9ec9f232760050782.png

想不想自己动手试试?

2.doc转PDF

doc文档转PDF就相对复杂了,需要引用外部控件jacob

jacob依赖包下载:

https://github.com/freemansoft/jacob-project/releases

以前依赖包可以直接在jacob官网下载,现在你去下载的话只能下载个README.md文件

解压下载得包,可以看到理念有三个比较重要得文件

4217e97c74d66512f8ec60b197ad734c.png

jacob.jar:Java工程中使用;

73d2ec9dc18a5f01eb84358c5e91eb22.png

cb54baa847768e31bee037adbef04751.png

jacob-1.20-x64.dll:放在windows系统为64的Java目录 jdk/jre/bin目录。

jacob-1.20-x32.dll:放在windows系统为32的Java目录 jdk/jre/bin目录。

例如:C:\Program Files\Java\jdk1.8.0_121\jre\bin

jacob-1.20-x64.dll、jacob-1.20-x32.dll 根据自己的电脑版本数选择

切记,一定加加上dll文件以及工程中依赖jar包;如果忘记加上dll,程序启动的时候不会报错,但是在执行的时候会抛异常,如果你没打出异常的话,你会一脸懵逼的不知道哪里出错了

贴上代码:

private boolean docFileToPdf(String docPath, String pdfOutPath) {
Boolean changeResult = false;ActiveXComponent app = null;
try{//打开word应用程序app = new ActiveXComponent("Word.Application");//设置word不可见app.setProperty("Visible", false);//获得word中所有打开的文档,返回Documents对象Dispatch docs = app.getProperty("Documents").toDispatch();//调用Documents对象中Open方法打开文档,并返回打开的文档对象DocumentDispatch doc = Dispatch.call(docs,"Open",docPath,
false,
true).toDispatch();//调用Document对象的SaveAs方法,将文档保存为pdf格式Dispatch.call(doc,"ExportAsFixedFormat",pdfOutPath,wdFormatPDF //word保存为pdf格式宏,值为17);//关闭文档Dispatch.call(doc, "Close",false);System.out.println("doc文档转PDF成功");changeResult = true;} catch (Exception e) {
System.out.println("doc文档转PDF失败");e.printStackTrace();}return changeResult;}

下面我们来看一下效果:

同样在D盘我们新建一个docx文档,内容如下,输出路径设置为D:/woshiluoshao.pdf

0b50fe8749ff7a3825a144ecc3284b0c.png

启动程序看看效果

692a2e850c5442dc3c9a1c7a5c0a3dca.png

5c0127f78a5837da036194f795869d31.png

以上只是我举的两个例子,图片支持:png、jpg、jpeg、gif等标准格式图片

doc文档支持doc、docx

其他比如excel、office等我没有举例。

是不是成功生成了。你以为这就结束了吗?不,还没有,还有一些隐藏的坑,我要慢慢跟你道来!

潜藏的坑:

(1)文件转PDF如果是doc等格式转换的话,只能在windows下部署运行,不能部署到linux下

(2)出现doc、excel等格式转换的前提,必须要先安装微软office软件,不然运行会报错

(3)如果出现错误:VariantChangeType failed 这个类型错误,处理方案如下:

  1.mmc comexp.msc -64

  2.组件服务-》我的电脑-》DCOM配置-》Microsoft Word 97 - 2003 文档-》标识改成交互式用户

   如果上诉还是不行,在C:\Windows\System32\config\systemprofile下创建文件夹Desktop即可

(4)jacob支持tomcat8.0以上版本、jdk1.8及以上版本,如果版本太低,也可能报错

代码不易,总结不易,且写且珍惜;各位看官,且看且珍惜,给个赞再走吧。

贴上我的公众号,喜欢请帮我推荐,谢谢

bf2a64ebab562905d4539fad40d54b75.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值