java操作word轉換pdf加水印

1,引入maven依賴

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j</artifactId>
            <version>6.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-export-fo</artifactId>
            <version>6.0.0</version>
        </dependency>

2,項目demo

package io.renren.controller;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.springframework.core.io.ClassPathResource;

import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class WordToPdf{
    private static String separator = File.separator;//文件夾路徑分格符

    //=========================================生成申請表pdf===================================

    /**
     * freemark生成word----docx格式
     * @param dataMap 數據源
     * @param documentXmlName  document.xml模板的文件名
     * @param docxTempName   docx模板的文件名
     * @return 生成的文件路徑
     */
    public static String createApplyPdf(Map<String,Object> dataMap,String documentXmlName,String docxTempName) {
        ZipOutputStream zipout = null;//word輸出流
        File tempPath = null;//docx格式的word文件路徑
        try {
            //freemark根據模板生成內容xml
            //================================獲取 document.xml 輸入流================================
            ByteArrayInputStream documentInput = FreeMarkUtils.getFreemarkerContentInputStream(dataMap, documentXmlName, separator + "template" + separator + "downLoad" + separator);
            //================================獲取 document.xml 輸入流================================
            //獲取主模板docx
            ClassPathResource resource = new ClassPathResource("template" + File.separator + "downLoad" + File.separator + docxTempName);
            File docxFile = resource.getFile();

            ZipFile zipFile = new ZipFile(docxFile);
            Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();

            //輸出word文件路徑和名稱
            String fileName = "applyWord_" + System.currentTimeMillis() + ".docx";
            String outPutWordPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;

            tempPath = new File(outPutWordPath);
            //如果輸出目標文件夾不存在,則創建
            if (!tempPath.getParentFile().exists()) {
                tempPath.mkdirs();
            }
            //docx文件輸出流
            zipout = new ZipOutputStream(new FileOutputStream(tempPath));

            //循環遍歷主模板docx文件,替換掉主內容區,也就是上面獲取的document.xml的內容
            //------------------覆蓋文檔------------------
            int len = -1;
            byte[] buffer = new byte[1024];
            while (zipEntrys.hasMoreElements()) {
                ZipEntry next = zipEntrys.nextElement();
                InputStream is = zipFile.getInputStream(next);
                if (next.toString().indexOf("media") < 0) {
                    zipout.putNextEntry(new ZipEntry(next.getName()));
                    if ("word/document.xml".equals(next.getName())) {
                        //寫入填充數據後的主數據信息
                        if (documentInput != null) {
                            while ((len = documentInput.read(buffer)) != -1) {
                                zipout.write(buffer, 0, len);
                            }
                            documentInput.close();
                        }
                    }else {//不是主數據區的都用主模板的
                        while ((len = is.read(buffer)) != -1) {
                            zipout.write(buffer, 0, len);
                        }
                        is.close();
                    }
                }
            }
            //------------------覆蓋文檔------------------
            zipout.close();//關閉

            //----------------word轉pdf--------------
            return convertDocx2Pdf(outPutWordPath);

        } catch (Exception e) {
            e.printStackTrace();
            try {
                if(zipout!=null){
                    zipout.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return "";
    }

    /**
     * word(docx)轉pdf
     * @param wordPath  docx文件路徑
     * @return  生成的帶水印的pdf路徑
     */
    public static String convertDocx2Pdf(String wordPath) {
        OutputStream os = null;
        InputStream is = null;
        try {
            is = new FileInputStream(new File(wordPath));
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
            Mapper fontMapper = new IdentityPlusMapper();
            fontMapper.put("隸書", PhysicalFonts.get("LiSu"));
            fontMapper.put("宋體", PhysicalFonts.get("SimSun"));
            fontMapper.put("微軟雅黑", PhysicalFonts.get("Microsoft Yahei"));
            fontMapper.put("黑體", PhysicalFonts.get("SimHei"));
            fontMapper.put("楷體", PhysicalFonts.get("KaiTi"));
            fontMapper.put("新宋體", PhysicalFonts.get("NSimSun"));
            fontMapper.put("華文行楷", PhysicalFonts.get("STXingkai"));
            fontMapper.put("華文仿宋", PhysicalFonts.get("STFangsong"));
            fontMapper.put("宋體擴展", PhysicalFonts.get("simsun-extB"));
            fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
            fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
            fontMapper.put("幼圓", PhysicalFonts.get("YouYuan"));
            fontMapper.put("華文宋體", PhysicalFonts.get("STSong"));
            fontMapper.put("華文中宋", PhysicalFonts.get("STZhongsong"));

            mlPackage.setFontMapper(fontMapper);

            //輸出pdf文件路徑和名稱
            String fileName = "pdfNoMark_" + System.currentTimeMillis() + ".pdf";
            String pdfNoMarkPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;

            os = new java.io.FileOutputStream(pdfNoMarkPath);

            //docx4j  docx轉pdf
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(mlPackage);
            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

            is.close();//關閉輸入流
            os.close();//關閉輸出流

            //添加水印
            return addTextMark(pdfNoMarkPath);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if(is != null){
                    is.close();
                }
                if(os != null){
                    os.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }finally {
            File file = new File(wordPath);
            if(file!=null&&file.isFile()&&file.exists()){
                file.delete();
            }
        }
        return "";
    }

    /**
     * 添加水印圖片
     * @param inPdfPath 無水印pdf路徑
     * @return 生成的帶水印的pdf路徑
     */
    private static String addTextMark(String inPdfPath) {
        PdfStamper stamp = null;
        PdfReader reader = null;
        try {
            //輸出pdf帶水印文件路徑和名稱
            String fileName = "pdfMark_" + System.currentTimeMillis() + ".pdf";
            String outPdfMarkPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;

            //添加水印
            reader = new PdfReader(inPdfPath, "PDF".getBytes());
            stamp = new PdfStamper(reader, new FileOutputStream(new File(outPdfMarkPath)));
            PdfContentByte under;
            int pageSize = reader.getNumberOfPages();// 原pdf文件的總頁數
            //水印圖片
            ClassPathResource resource = new ClassPathResource("template" + File.separator + "downLoad" + File.separator + "mark.png");
            File file = resource.getFile();
            Image image = Image.getInstance(file.getPath());
            for (int i = 1; i <= pageSize; i++) {
                under = stamp.getUnderContent(i);// 水印在之前文本下
                image.setAbsolutePosition(100, 210);//水印位置
                under.addImage(image);
            }
            stamp.close();// 關閉
            reader.close();//關閉

            return outPdfMarkPath;
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (stamp != null) {
                    stamp.close();
                }
                if (reader != null) {
                    reader.close();//關閉
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } finally {
            //刪除生成的無水印pdf
            File file = new File(inPdfPath);
            if (file != null && file.exists() && file.isFile()) {
                file.delete();
            }
        }
        return "";
    }

    public static void main(String[] args) {
//        createApplyPdf();
//        convert();
//        addTextMark("D:\\test\\test.pdf", "D:\\test\\test2.pdf");
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章