前端需要预览word文件,浏览器不能预览doc格式,但是可以预览pdf,所以将word转成pdf格式提供预览
1.word转pdf
链接: https://pan.baidu.com/s/1Ab97kVVy1DPCLQ2725N3vg?pwd=hcnx 提取码: hcnx
1.引入本地jar包
在maven的bin目录下输入cmd进入执行命令
mvn install:install-file -DgroupId=com.aspose.words -DartifactId=aspose-words -Dversion=19.5 -Dpackaging=jar -Dfile=jar包的路径
2.在pom中加入依赖,和配置文件
<dependency>
<groupId>com.aspose.words</groupId>
<artifactId>aspose-words</artifactId>
<version>19.5</version>
</dependency>
将xml文件放在resource下(若不验证则转化出的pdf文档会有水印产生)
3.工具类AsposeUtil
package com.test.mybatistest.util;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
public class AsposeUtil {
public static void main(String[] args) throws Exception {
//将doc文件转换为pdf
AsposeUtil bean = new AsposeUtil();
bean.toPdf("F:\\file\\test.doc", "F:\\file\\testTopdf.pdf");
}
/**
* word转pdf
*
* @param inpath
* @param outpath
* @throws Exception
*/
public void toPdf(String inpath, String outpath) throws Exception {
if (!getLicense()) {
System.out.println("非法------------");
return;
}
System.out.println("开始使用Aspose.words进行转换");
long old = System.currentTimeMillis();
File file = new File(outpath);
FileOutputStream os = new FileOutputStream(file);
String osName = System.getProperty("os.name", "");
if (osName.startsWith("Mac OS")) {
//mac环境
} else if (osName.startsWith("Windows")) {
//windows环境
} else {
// linux环境 如果环境缺少中文字体会发生转换乱码
new FontSettings().setFontsFolder("/usr/share/fonts/chinese", true);
}
Document doc = new Document(inpath);
doc.save(os, SaveFormat.PDF);
long now = System.currentTimeMillis();
System.out.println("Aspose.words转换结束,共耗时:" + ((now - old) / 1000.0) + "秒");
}
/**
* 验证License 若不验证则转化出的pdf文档会有水印产生
*
* @return
*/
public boolean getLicense() {
boolean result = false;
try {
InputStream is = this.getClass().getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
4.转换测试使用
2.pdf转word
1.依赖
<repositories>
<repository>
<id>aspose-maven-repository</id>
<url>https://repository.aspose.com/repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories><dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-pdf</artifactId>
<version>22.4</version>
</dependency>
2.破解jar包
先引入官方的包,找到maven仓库位置,执行util破解,替换生产的jar包(不破解的话只处理前4页的转换)
PDFJarCrack破解的util
执行后生成cracked文件,将原文件备份改为_back
package com.test.mybatistest.util;
import javassist.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;public class PDFJarCrack {
public static void main(String[] args) throws Exception {//填写自己下载的jar包地址
String jarPath = "F:\\maven\\apache-maven-3.6.3-bin\\maven-repository\\com\\aspose\\aspose-pdf\\22.4\\aspose-pdf-22.4.jar";
crack(jarPath);
}private static void crack(String jarName) {
try {
ClassPool.getDefault().insertClassPath(jarName);
CtClass ctClass = ClassPool.getDefault().getCtClass("com.aspose.pdf.ADocument");
CtMethod[] declaredMethods = ctClass.getDeclaredMethods();
int num = 0;
for (int i = 0; i < declaredMethods.length; i++) {
if (num == 2) {
break;
}
CtMethod method = declaredMethods[i];
CtClass[] ps = method.getParameterTypes();
if (ps.length == 2
&& method.getName().equals("lI")
&& ps[0].getName().equals("com.aspose.pdf.ADocument")
&& ps[1].getName().equals("int")) {
// 最多只能转换4页 处理
System.out.println(method.getReturnType());
System.out.println(ps[1].getName());
method.setBody("{return false;}");
num = 1;
}
if (ps.length == 0 && method.getName().equals("lt")) {
// 水印处理
method.setBody("{return true;}");
num = 2;
}
}
File file = new File(jarName);
ctClass.writeFile(file.getParent());
disposeJar(jarName, file.getParent() + "/com/aspose/pdf/ADocument.class");
} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}}
private static void disposeJar(String jarName, String replaceFile) {
List<String> deletes = new ArrayList<>();
deletes.add("META-INF/37E3C32D.SF");
deletes.add("META-INF/37E3C32D.RSA");
File oriFile = new File(jarName);
if (!oriFile.exists()) {
System.out.println("######Not Find File:" + jarName);
return;
}
//将文件名命名成备份文件
String bakJarName = jarName.substring(0, jarName.length() - 3) + "cracked.jar";
// File bakFile=new File(bakJarName);
try {
//创建文件(根据备份文件并删除部分)
JarFile jarFile = new JarFile(jarName);
JarOutputStream jos = new JarOutputStream(new FileOutputStream(bakJarName));
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = (JarEntry) entries.nextElement();
if (!deletes.contains(entry.getName())) {
if (entry.getName().equals("com/aspose/pdf/ADocument.class")) {
System.out.println("Replace:-------" + entry.getName());
JarEntry jarEntry = new JarEntry(entry.getName());
jos.putNextEntry(jarEntry);
FileInputStream fin = new FileInputStream(replaceFile);
byte[] bytes = readStream(fin);
jos.write(bytes, 0, bytes.length);
} else {
jos.putNextEntry(entry);
byte[] bytes = readStream(jarFile.getInputStream(entry));
jos.write(bytes, 0, bytes.length);
}
} else {
System.out.println("Delete:-------" + entry.getName());
}
}
jos.flush();
jos.close();
jarFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}private static byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
}
替换完jar包后,使用工具类转换 PdfUtils,就不会有只转换4页的问题
package com.test.mybatistest.util;
import com.aspose.pdf.Document;
import com.aspose.pdf.SaveFormat;import java.io.FileOutputStream;
import java.io.IOException;
public class PdfUtils {public static void main(String[] args) throws IOException {
pdf2doc("F:\\file\\pdf\\test.pdf");
}//pdf转doc
public static void pdf2doc(String pdfPath) {
long old = System.currentTimeMillis();
try {
//新建一个word文档
String wordPath = pdfPath.substring(0, pdfPath.lastIndexOf(".")) + ".docx";
FileOutputStream os = new FileOutputStream(wordPath);
//doc是将要被转化的word文档
Document doc = new Document(pdfPath);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, SaveFormat.DocX);
os.close();
//转化用时
long now = System.currentTimeMillis();
System.out.println("Pdf 转 Word 共耗时:" + ((now - old) / 1000.0) + "秒");
} catch (Exception e) {
System.out.println("Pdf 转 Word 失败...");
e.printStackTrace();
}
}
}
执行成功
3.配合minio使用
minio一起使用,当前项目使用的minio存储文件,在项目里做word转换为pdf,保存自己需要的文件,删除转换过程产生的文件
Minio部分的代码
package com.test.mybatistest.minio;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.pagehelper.util.StringUtil;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
@Api(tags = "Minio")
@RestController
@Slf4j
@RequestMapping("/minio")
public class MinioController {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfig minioConfig;
@Value("${minio.bucketName}")
private String bucketName;
/**
* 文件上传
*
* @param file
* @return
*/
@ApiOperation("文件上传-批量")
@PostMapping("/upload")
public Object upload(@RequestParam(name = "file", required = false) MultipartFile[] file) {
if (file == null || file.length == 0) {
return "上传文件不能为空";
}
List<FileResult> result = new ArrayList<>();
for (MultipartFile multipartFile : file) {
//3.文件上传
try {
String original = multipartFile.getOriginalFilename();
String last = getFileExtension(original);
if ("doc".equalsIgnoreCase(last) || "docx".equalsIgnoreCase(last)) {
result.add(saveWordToPdf(multipartFile, original));
} else {//其他文件的保存
result.add(putFile(fileName(original), original, multipartFile.getInputStream()));
}
} catch (Exception e) {
return "上传失败";
}
}
return result;
}
/**
* 保存文件的
*
* @param fileName
* @param original
* @param stream
* @return
* @throws Exception
*/
private FileResult putFile(String fileName, String original, InputStream stream) throws Exception {
//fileName 处理后的文件名,orgfileName 原文件名
String contentType = ViewContentType.getContentType(fileName);
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(stream, stream.available(), -1)
.contentType(contentType)
.build());
FileResult fileResult = new FileResult();
fileResult.setOrgName(original);
fileResult.setFileName(fileName);
fileResult.setPath(fileLink(bucketName, fileName));
return fileResult;
}
/**
* 保存一份word原文件,并生成一份pdf
*
* @param file
* @param original
* @return
* @throws Exception
*/
private FileResult saveWordToPdf(@RequestParam MultipartFile file, String original) throws Exception {
//获取文件原名和原格式,生成保存的文件名 aaa.docx
String fileName = fileName(original); // upload/20230310/uuid.docx
//先保存一份原文件
FileResult fileResult = this.putFile(fileName, original, file.getInputStream());
//转换为pdf文件,并保存处理
changPdfAndSave(file, original, fileName);
return fileResult;
}
/**
* 转换pdf并保存
*
* @param file
* @param original
* @param fileName
* @throws Exception
*/
private void changPdfAndSave(@RequestParam MultipartFile file, String original, String fileName) throws Exception {
String name = getFileName(original);//获取原文件名
FileInputStream fileInputStream = new FileInputStream(FileUtils.multipartFileToFile(file));
if (!getLicense()) {
System.out.println("非法------------");
return;
}
String docPath = "";
String pdfPath = "";
//根据环境判断项目路径,保存到项目里,在使用后需要删除
docPath = getSystemPath() + "/" + original;
pdfPath = getSystemPath() + "/" + name + ".pdf";
String subName = getFileName(fileName) + ".pdf";
String subfileName = name + ".pdf";
File fileOut = new File(pdfPath);
FileOutputStream os = new FileOutputStream(fileOut);
Document doc = new Document(fileInputStream);
doc.save(os, SaveFormat.PDF);
InputStream inputStream = FileUtils.fileToInputStream(new File(pdfPath));
this.putFile(subName, subfileName, inputStream);
//关闭流
fileInputStream.close();
inputStream.close();
os.close();
//删除原文件和生成的pdf文件
FileUtils.deleteFileOrDirectory(docPath);
FileUtils.deleteFileOrDirectory(pdfPath);
}
/**
* 获取项目地址
*
* @param
* @return
*/
private String getSystemPath() {
String path = new String();
String osName = System.getProperty("os.name", "");
if (osName.startsWith("Mac OS")) {
//mac
} else if (osName.startsWith("Windows")) {
//windows
path = System.getProperty("user.dir");
} else {
//在linux里获取的地址为 data/project/project.jar 截取最后一个斜杠data/project/
String url = System.getProperty("java.class.path");
path = url.substring(0, url.lastIndexOf("/"));
//如果是linux执行,需要添加这个,如果还有乱码需要在linux下安装中文字体
new FontSettings().setFontsFolder("/usr/share/fonts/chinese", true);
}
return path;
}
/**
* 创建访问路径
*
* @param bucketName
* @param fileName
* @return
*/
private String fileLink(String bucketName, String fileName) {
return minioConfig.getEndpoint() + '/' + bucketName + '/' + fileName;
}
/**
* 验证License 若不验证则转化出的pdf文档会有水印产生
*
* @return
*/
public boolean getLicense() {
boolean result = false;
try {
InputStream is = this.getClass().getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 生成图片名称
*
* @param originalFilename
* @return
*/
public String fileName(String originalFilename) {
StringBuffer sb = new StringBuffer();
String yyyyMMdd = new SimpleDateFormat("yyyyMMdd").format(new Date());
ThreadLocalRandom random = ThreadLocalRandom.current();
String uuid = new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
sb.append("upload").append("/")
.append(yyyyMMdd).append("/")
.append(uuid).append(".")
.append(getFileExtension(originalFilename));
return sb.toString();
}
/**
* 获取文件后缀
*
* @param fullName
* @return
*/
public static String getFileExtension(String fullName) {
if (StringUtil.isEmpty(fullName)) return StringPool.EMPTY;
String fileName = new File(fullName).getName();
int dotIndex = fileName.lastIndexOf(".");
return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
}
/**
* 获取文件名字
*
* @param fullName
* @return
*/
public static String getFileName(String fullName) {
if (StringUtil.isEmpty(fullName)) return StringPool.EMPTY;
//String fileName = new File(fullName).getName();//不需要路径的名称
int dotIndex = fullName.lastIndexOf(".");//带路径的文件名称
return (dotIndex == -1) ? "" : fullName.substring(0, dotIndex);
}
}
文件流转换的Util
package com.test.mybatistest.minio;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
* file工具类
*/
public class FileUtils {
/**
* file转InputStream
*
* @param file
* @return
*/
public static InputStream fileToInputStream(File file) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return inputStream;
}
/**
* file转OutputStream
*
* @param file
* @return
*/
public static OutputStream fileToOutputStream(File file) {
OutputStream inputStream = null;
try {
inputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return inputStream;
}
/**
* file转mult
*
* @param file
* @return
*/
public static MultipartFile fileToMultipartFile(File file) {
MultipartFile result = null;
if (null != file) {
try (FileInputStream input = new FileInputStream(file)) {
result = new MockMultipartFile(file.getName().concat("temp"), file.getName(), "text/plain", input);
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* MultipartFile转换为file
*
* @param file
* @return
*/
public static File multipartFileToFile(MultipartFile file) {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
try {
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
try {
ins.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return toFile;
}
/**
* inputStream 转file
* @param ins
* @param file
*/
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除文件或文件夹
* @param fileName
* @return
*/
public static boolean deleteFileOrDirectory(String fileName) {
File file = new File(fileName); // fileName是路径或者file.getPath()获取的文件路径
if (file.exists()) {
if (file.isFile()) {
return deleteFile(fileName); // 是文件,调用删除文件的方法
} else {
return deleteDirectory(fileName); // 是文件夹,调用删除文件夹的方法
}
} else {
System.out.println("文件或文件夹删除失败:" + fileName);
return false;
}
}
/**
* 删除文件
*
* @param fileName 文件名
* @return 删除成功返回true, 失败返回false
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
if (file.isFile() && file.exists()) {
file.delete();
System.out.println("删除文件成功:" + fileName);
return true;
} else {
System.out.println("删除文件失败:" + fileName);
return false;
}
}
/**
* 删除文件夹
* 删除文件夹需要把包含的文件及文件夹先删除,才能成功
*
* @param directory 文件夹名
* @return 删除成功返回true, 失败返回false
*/
public static boolean deleteDirectory(String directory) {
// directory不以文件分隔符(/或\)结尾时,自动添加文件分隔符,不同系统下File.separator方法会自动添加相应的分隔符
if (!directory.endsWith(File.separator)) {
directory = directory + File.separator;
}
File directoryFile = new File(directory);
// 判断directory对应的文件是否存在,或者是否是一个文件夹
if (!directoryFile.exists() || !directoryFile.isDirectory()) {
System.out.println("文件夹删除失败,文件夹不存在" + directory);
return false;
}
boolean flag = true;
// 删除文件夹下的所有文件和文件夹
File[] files = directoryFile.listFiles();
for (int i = 0; i < files.length; i++) { // 循环删除所有的子文件及子文件夹
// 删除子文件
if (files[i].isFile()) {
flag = deleteFile(files[i].getAbsolutePath());
if (!flag) {
break;
}
} else { // 删除子文件夹
flag = deleteDirectory(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
}
if (!flag) {
System.out.println("删除失败");
return false;
}
// 最后删除当前文件夹
if (directoryFile.delete()) {
System.out.println("删除成功:" + directory);
return true;
} else {
System.out.println("删除失败:" + directory);
return false;
}
}
public static File Dwg2Pdf(File dwgFile) throws IOException {
return null;
}
}
文件file类
package com.test.mybatistest.minio;
import lombok.Data;
import java.io.Serializable;
@Data
public class FileResult implements Serializable {
/**
* 文件原名
*/
private String orgName;
/**
* 文件路径
*/
private String fileName;
/**
* 文件访问路径
*/
private String path;
}
测试使用,pdf文件预览
4.在linux里做转换时的乱码问题
链接: https://pan.baidu.com/s/1-0OgdOL1BYp-cSS9qfUMOQ?pwd=1qif 提取码: 1qif
需要在linux下安装中文的字体库
将chinese,放在/usr/share下,没有fonts文件就创建
将下载的rpm文件放在需要安装字体的服务器上,执行
rpm -ivh fontconfig-2.13.0-4.3.el7.i686.rpm --nodeps --force
rpm -ivh ttmkfdir-3.0.9-42.el7.x86_64.rpm --nodeps --force
安装ttmkfdir来搜索目录中所有的字体信息,并汇总生成fonts.scale文件。
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
看看etc下有没有fonts文件,没有就将fonts放在/etc/fonts下
vi /etc/fonts/fonts.conf 修改新的字体路径
<dir>/usr/share/fonts/chinese</dir>
fc-cache 刷新缓存
fc-list 查看字体
安装字体也可解决,压缩文件乱码问题
unzip -O CP936 中文的zip文件.zip
参考
linux离线安装字体_linux 离线安装字体_涟漪海洋的博客-CSDN博客
java word转pdf(完美转换,亲测可用)_java word转pdf完美解决_CxNull的博客-CSDN博客
Java实现PDF转Word-CSDN博客