前言
图片、word转pdf文档方法
代码如下(示例):
/**
* 图片、word转pdf
*
* @param fileType 文件类型
* @param sourcePath 文件网络路径
* @param saveFileName 文件保存名字
* @param folderName 文件保存根目录
*/
public void convertToPdf(String fileType, String sourcePath, String saveFileName, String folderName) {
String fileSavePath = saveFileToLocal(sourcePath, saveFileName, folderName);
File file = null;
// 生成随机文件名
String pdfFileName = UUID.randomUUID().toString().replace("-", "") + ".pdf";
if (StringUtils.equalsIgnoreCase(fileType, ".doc") || StringUtils.equalsIgnoreCase(fileType, ".docx")) {
// word文件转成PDF文件
file = wordToPdf(fileSavePath + saveFileName, fileSavePath + pdfFileName);
} else if (StringUtils.equalsIgnoreCase(fileType, ".jpg") || StringUtils.equalsIgnoreCase(fileType, ".jpeg") || StringUtils.equalsIgnoreCase(fileType, ".png")) {
// 图片文件转成PDF文件
file = imageToPdf(new File(fileSavePath + saveFileName), fileSavePath + pdfFileName);
} else if (StringUtils.equalsIgnoreCase(fileType, ".pdf")) {
file = new File(fileSavePath + saveFileName);
} else {
throw new ServiceException("文件无效");
}
if (file == null) {
throw new ServiceException("文件转换失败");
}
// 删除临时生成的文件夹及其子文件夹和子文件
deleteDirectory(new File(fileSavePath));
}
/**
* word转pdf
*
* @param source 源文件路径
* @param target 生成文件目标路径
* @return pdf文本
*/
public static File wordToPdf(String source, String target) {
try {
WordprocessingMLPackage pkg = Docx4J.load(new File(source));
Mapper fontMapper = new IdentityPlusMapper();
//解决宋体(正文)和宋体(标题)的乱码问题
PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("仿宋", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("黑体", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("等线", PhysicalFonts.get("SimSun"));
//将字体替换为服务器中存在的字体
fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
fontMapper.put("仿宋_GB2312", PhysicalFonts.get("STFangsong"));
fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
fontMapper.put("SimSun", simsunFont);
//设置字体
pkg.setFontMapper(fontMapper);
Docx4J.toPDF(pkg, new FileOutputStream(target));
return new File(target);
} catch (Exception e) {
e.printStackTrace();
log.error("word转pdf失败!");
}
return null;
}
/**
* 图片转pdf
*
* @param imageFile 图片文件
* @param retFile 输出的pdf文件
* @return
*/
public static File imageToPdf(File imageFile, String retFile) {
try {
MultipartFile multipartFile = getMultipartFile(imageFile);
Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
PdfWriter.getInstance(doc, new FileOutputStream(retFile));
doc.open();
doc.newPage();
Image image = Image.getInstance(multipartFile.getBytes());
float height = image.getHeight();
float width = image.getWidth();
int percent = getPercent(height, width);
image.setAlignment(Image.MIDDLE);
image.scalePercent(percent);
doc.add(image);
doc.close();
File pdfFile = new File(retFile);
return pdfFile;
} catch (Exception e) {
e.printStackTrace();
log.error("图片转pdf失败!");
}
return null;
}
/**
* 获取图片对比A4纸的比例
*
* @param height 高度
* @param weight 宽度
* @return 比例
*/
private static int getPercent(float height, float weight) {
float percent = 0.0F;
if (height > weight) {
percent = PageSize.A4.getHeight() / height * 100;
} else {
percent = PageSize.A4.getWidth() / weight * 100;
}
return Math.round(percent);
}
public static MultipartFile getMultipartFile(File file) {
FileItem item = new DiskFileItemFactory().createItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName());
try (InputStream input = new FileInputStream(file);
OutputStream os = item.getOutputStream()) {
// 流转移
IOUtils.copy(input, os);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid file: " + e, e);
}
return new CommonsMultipartFile(item);
}
/**
* 将文件保存至本地
*
* @param filePath 原始文件路径
* @param saveFileName 文件保存父文件夹
* @param saveFolder 文件保存根文件夹
* @return
*/
private String saveFileToLocal(String filePath, String saveFileName, String saveFolder) {
log.info("saveFileToLocal方法开始. ");
FileOutputStream outputStream = null;
InputStream inputStream = null;
try {
HttpURLConnection httpUrl = (HttpURLConnection) new URL(filePath).openConnection();
httpUrl.connect();
inputStream = httpUrl.getInputStream();
// 根据时间戳创建文件
String dateFolderName = System.currentTimeMillis() + "/";
log.info("时间戳创建文件: {}. ", dateFolderName);
File file = new File(saveFolder + dateFolderName);
log.info("时间戳创建文件对象: {}. ", file);
if (!file.exists()) {
log.info("准备创建文件夹. ");
file.mkdirs();// 如果不存在,创建目录
log.info("成功创建文件夹. ");
}
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
log.info("准备输出文件. ");
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
File outFile = new File(saveFolder + dateFolderName + saveFileName);
FileOutputStream fops = new FileOutputStream(outFile);
fops.write(outStream.toByteArray());
log.info("输出文件完成. ");
fops.flush();
return saveFolder + dateFolderName;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
}
}
}
}
/**
* 删除文件夹及其子文件夹和子文件
*
* @param dir 待删除文件夹
* @return
*/
public static boolean deleteDirectory(File dir) {
if (dir.isDirectory()) {
File[] subFiles = dir.listFiles();
for (int i = 0; i < subFiles.length; i++) {
boolean success = deleteDirectory(subFiles[i]);
if (!success) {
return false;
}
}
}
return dir.delete();
}
注:
- word转pdf容易乱码,需要在容器中安装字体,如果容器中没有,要将word中的字体替换成容器中有的
WordprocessingMLPackage pkg = Docx4J.load(new File(source));
Mapper fontMapper = new IdentityPlusMapper();
// 将仿宋_GB2312替换为仿宋
fontMapper.put("仿宋_GB2312", PhysicalFonts.get("STFangsong"));
pkg.setFontMapper(fontMapper);
- word转pdf仅支持docx格式,不支持doc格式
- 如果运行环境不是linux,推荐使用documents4j做word转pdf,方便且效率高
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-local</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-transformer-msoffice-word</artifactId>
<version>1.1.1</version>
</dependency>