Word和pdf转换

前端需要预览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博客
 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值