zoukankan      html  css  js  c++  java
  • 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");
        }
    
    }
    
    
  • 相关阅读:
    【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】
    CF980E The Number Games【树链剖分/线段树】
    【扫描线模板】
    【洛谷】3402:【模板】可持久化并查集
    【洛谷】1525:关押罪犯【并查集】【二分+二分图判断】
    【洛谷】4180:【模板】严格次小生成树[BJWC2010]【链剖】【线段树维护最大、严格次大值】
    【POJ】2796:Feel Good【单调栈】
    【POJ】1862:Stripies【贪心】【优先队列】
    《中间人攻击——wikipedia》——学习摘要
    《中间人攻击——ARP欺骗的原理、实战及防御》——学习摘要
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13300570.html
Copyright © 2011-2022 走看看