精华内容
下载资源
问答
  • docx4j word转pdf

    2019-08-07 02:12:18
    NULL 博文链接:https://01jiangwei01.iteye.com/blog/2124289
  • word转pdf所用docx4j

    2019-03-14 21:31:50
    docx4j 用的jar包,docx4j学习网址:http://www.docx4java.org/trac/docx4j
  • docx4j word合并转pdf.zip

    2019-09-25 14:26:53
    使用docx4j相关jar包,实现多个word文档合并,并转为pdf文档格式
  • docx4j实现docx转pdf.rar

    2019-12-31 16:48:51
    文档中,包含说明文档、lib架包以及工具类的代码。说明文档中,包含了工程依赖(maven...包你拿到手,立马就能实现docx转word功能。工具类的代码,已经排出了测试代码的各种坑,可以实现文字替换、表格替换等系列功能。
  • 利用docx4j word转pdf

    千次阅读 热门讨论 2019-07-24 15:53:24
    依赖: <docx4j.version>6.1.1</docx4j.version> <export.fo.version>.../export.fo.version>...--word pdf --> <dependency> <groupId>org.docx4j</groupI...

    依赖:

    <docx4j.version>6.1.1</docx4j.version>
    <export.fo.version>8.1.1</export.fo.version>
    
      <!--word 转 pdf -->
    <dependency>
       <groupId>org.docx4j</groupId>
       <artifactId>docx4j</artifactId>
       <version>${docx4j.version}</version>
    </dependency>
    <dependency>
       <groupId>org.docx4j</groupId>
       <artifactId>docx4j-export-fo</artifactId>
       <version>${export.fo.version}</version>
    </dependency>

    工具类

    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.io.FileUtils;
    import org.apache.poi.xwpf.usermodel.*;
    import org.docx4j.Docx4J;
    import org.docx4j.fonts.IdentityPlusMapper;
    import org.docx4j.fonts.Mapper;
    import org.docx4j.fonts.PhysicalFonts;
    import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
    import org.docx4j.org.apache.poi.util.IOUtils;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    @Slf4j
    public class WordUtils {
    
        public static void main(String[] args) throws Exception {
            WordUtils.convertDocxToPdf("D:/test.docx","D:/test.pdf");
        }
    
        /**
         * docx文档转换为PDF
         * @param body 文档
         * @param response 响应给前端
         * @return pdf 输出流
         * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
         */
        public static void convertDocxToPdf(byte[] body , HttpServletResponse response) throws Exception {
            response.setContentType("application/pdf");
            File docxFile = FileUtil.byteToFile(body, UUID.randomUUID().toString() + ".docx");
            try {
                WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docxFile);
                setFontMapper(mlPackage);
                Docx4J.toPDF(mlPackage, response.getOutputStream());
            }catch (Exception e){
                e.printStackTrace();
                log.error("docx文档转换为PDF失败");
            }
           FileUtil.deleteTempFile(docxFile);
        }
    
    
    
        /**
         * docx文档转换为PDF
         *
         * @param pdfPath PDF文档存储路径
         * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
         */
        public static void convertDocxToPdf(String docxPath, String pdfPath) throws Exception {
    
            FileOutputStream fileOutputStream = null;
            try {
                File file = new File(docxPath);
                fileOutputStream = new FileOutputStream(new File(pdfPath));
                WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);
                setFontMapper(mlPackage);
                Docx4J.toPDF(mlPackage, new FileOutputStream(new File(pdfPath)));
            }catch (Exception e){
                e.printStackTrace();
                log.error("docx文档转换为PDF失败");
            }finally {
                IOUtils.closeQuietly(fileOutputStream);
            }
        }
    
        private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {
            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);
        }
    }

    太多的word转pdf搜索出来的资料,版本号不是太旧,就是太繁琐,或者仅支持window,折腾了两天,最后还好找对了资料:https://blog.csdn.net/Jason_996/article/details/81707485

    感谢这位博主。虽然版本有点旧,但我整了一下,发现居然只用了两个依赖就能实现了。注:数学部分特殊字符无法正常转换

    相关工具类:

    import java.util.Arrays;
    
    public class CalculateUtil {
    
    
       public static Integer add(Integer... integers){
           return Arrays.stream(integers).filter(integer -> integer!=null).reduce(0, (a, b) -> a + b);
       }
    
        public static void main(String[] args) {
            Integer integer = new Integer(1);
            Integer first = null;
            Integer add = add(integer, first);
            System.out.println(add);
        }
    
    }
    
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import lombok.extern.slf4j.Slf4j;
    
    
    @Slf4j
    public final class FileUtil {
    
    	public static final String XLSX_SUFFIX = ".xlsx";
    
    	private FileUtil() {
    	}
    
    	/**
    	 * 文件转比特流
    	 */
    	public static byte[] fileToByte(String filePath) {
    		File file = new File(filePath);
    		return FileUtil.fileToByte(file);
    	}
    
    	/**
    	 * 文件转比特流
    	 */
    	public static byte[] fileToByte(File file) {
    		byte[] buffer = null;
    		try {
    			FileInputStream fis = new FileInputStream(file);
    			ByteArrayOutputStream bos = new ByteArrayOutputStream();
    			byte[] b = new byte[1024];
    			int n;
    			while ((n = fis.read(b)) != -1) {
    				bos.write(b, 0, n);
    			}
    			fis.close();
    			bos.close();
    			buffer = bos.toByteArray();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return buffer;
    	}
    
    	/**
    	 * 比特流转文件
    	 */
    	public static File byteToFile(byte[] buf, String fileName) {
    		BufferedOutputStream bos = null;
    		FileOutputStream fos = null;
    		File file = null;
    		try {
    
    			file = new File(fileName);
    			fos = new FileOutputStream(file);
    			bos = new BufferedOutputStream(fos);
    			bos.write(buf);
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (bos != null) {
    				try {
    					bos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			if (fos != null) {
    				try {
    					fos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    
    		return file;
    	}
    
    	/**
    	 * 删除临时文件
    	 */
    	public static void deleteTempFile(File file) {
    		if (file == null) {
    			return;
    		}
    		boolean delete = file.delete();
    		if (!delete) {
    			log.error("删除临时文件失败");
    		}
    	}
    
    	/**
    	 * 返回带点的后缀
    	 * 
    	 * @param ext
    	 * @return
    	 */
    	public static String getExt(String ext) {
    		return ext.indexOf(".") == -1 ? "." + ext : ext;
    	}
    
    	/**
    	 * 返回一个临时文件名不带后缀
    	 * 
    	 * @return
    	 */
    	public static String createTempFileName() {
    		String folder = System.getProperty("java.io.tmpdir");
    		String filename = folder + UUID.randomUUID();
    		return filename;
    	}
    
    	/**
    	 * 截取文件的后缀名 无后缀返回“”
    	 * 
    	 * @param fileName
    	 * @return
    	 */
    	public static String cutFileName(String fileName) {
    		String ext = StringUtil.cutName(fileName, ".");
    		return ext == null ? "" : ext;
    	}
    
    	/**
    	 * 生成一个临时文件
    	 */
    	public static File tempFile(String suffix) {
    		String folder = System.getProperty("java.io.tmpdir");
    		String fileName = System.currentTimeMillis() + suffix;
    		String s = folder + fileName;
    		return new File(s);
    	}
    
    	/**
    	 * 生成临时文件和file文件名字一样的
    	 */
    	public static File tempFile(File file) {
    		String folder = System.getProperty("java.io.tmpdir");
    		String s = folder + file.getName();
    		return new File(s);
    	}
    
    	/**
    	 * 创建一个临时目录 + 文件名字符串
    	 */
    	public static String getTempFileName(String fileName) {
    		String folder = System.getProperty("java.io.tmpdir");
    		return folder + "/" + fileName;
    
    	}
    
    	/**
    	 * 同名文件命名, 例如 1. a.pdf --> a(1).pdf 2. a --> a(1) 3. a(1).pdf --> a(2).pdf
    	 * 4. a(1) --> a(2)
    	 * 
    	 * @param fileName
    	 * @return
    	 */
    	public static String renameSameFileName(String fileName) {
    		String newFileName = null;
    		int i = fileName.lastIndexOf(".");
    		if (i != -1) { // 有同名文件,有.作为后缀
    			String rule = "(.*)\\.(.*)";
    			Matcher matcher = Pattern.compile(rule).matcher(fileName);
    
    			if (matcher.find()) {
    				String fileNameNoSuffix = matcher.group(1); // 文件名
    				String suffix = matcher.group(2);
    				String rule2 = "(.*)\\((\\d)\\)";
    				Matcher matcher1 = Pattern.compile(rule2).matcher(fileNameNoSuffix);
    				if (matcher1.find()) {// 同名的文件名是 文件名(1).pdf 这种
    					String number = matcher1.group(2);
    					Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);
    					newFileName = fileNameNoSuffix.replaceAll(rule2, "$1").concat("(" + newNumber + ").")
    							.concat(suffix);
    				} else { // 同名的文件名是 文件名.pdf这种 直接添加 (1).pdf
    					newFileName = fileName.replaceAll(rule, "$1(1).$2");
    				}
    			}
    		} else {// 有同名文件,没有以.作为后缀
    			String rule2 = "(.*)\\((\\d)\\)";
    			Matcher matcher1 = Pattern.compile(rule2).matcher(fileName);
    			if (matcher1.find()) {// 同名的文件名是 文件名(1) 这种
    				String number = matcher1.group(2);
    				Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);
    				newFileName = fileName.replaceAll(rule2, "$1").concat("(" + newNumber + ")");
    			} else {
    				newFileName = fileName.concat("(1)");
    			}
    		}
    		return newFileName;
    	}
    
    	/**
    	 * 截取 /sdfs/sdfsdf.pdf 中的sdfsdf.pdf
    	 * 
    	 * @param filePath
    	 * @return
    	 */
    	public static String getFileNameByPath(String filePath) {
    		String rule = "(.*/)(.*)";
    		String fileName = filePath.replaceAll(rule, "$2");
    		return fileName;
    	}
    }
    
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    
    public class StringUtil extends StringUtils {
    
        /**
         * 转换为下划线
         *
         * @param camelCaseName
         * @return
         */
        public static String underscoreName(String camelCaseName) {
            StringBuilder result = new StringBuilder();
            if (camelCaseName != null && camelCaseName.length() > 0) {
                result.append(camelCaseName.substring(0, 1).toLowerCase());
                for (int i = 1; i < camelCaseName.length(); i++) {
                    char ch = camelCaseName.charAt(i);
                    if (Character.isUpperCase(ch)) {
                        result.append("_");
                        result.append(Character.toLowerCase(ch));
                    } else {
                        result.append(ch);
                    }
                }
            }
            return result.toString();
        }
    
        /**
         * 转换为驼峰
         *
         * @param underscoreName
         * @return
         */
        public static String camelCaseName(String underscoreName) {
            StringBuilder result = new StringBuilder();
            if (underscoreName != null && underscoreName.length() > 0) {
                boolean flag = false;
                for (int i = 0; i < underscoreName.length(); i++) {
                    char ch = underscoreName.charAt(i);
                    if ("_".charAt(0) == ch) {
                        flag = true;
                    } else {
                        if (flag) {
                            result.append(Character.toUpperCase(ch));
                            flag = false;
                        } else {
                            result.append(ch);
                        }
                    }
                }
            }
            return result.toString();
        }
    
    
        /**
         * 截取文件后缀
         */
        public static String cutName(String fileName,String cutString){
            int i = fileName.lastIndexOf(cutString);
            if (i==-1) {
                return null;
            }else{
                return fileName.substring(i + 1);
            }
        }
    
        /**
         * 劈开某个字符串得到list
         */
        public static List<String> splitString(String source,String str){
            List<String> list = new ArrayList<>();
            String[] split = source.split(str);
            Collections.addAll(list,split);
            return list;
        }
    
    
        /**
         * 去除正则的特殊符号 ( )
         */
        public static String removeRegex(String source){
            return source.replaceAll("\\(|\\)", "");
        }
    
        /**
         * 去除空白符 再去除 正则特殊符号
         */
        public static String removeBlankAndRegex(String source){
            return removeRegex(removeBlank(source));
        }
    
        /**
         * 去除空白符
         */
        public static String removeBlank(String source){
            return source.replaceAll("\\s", "");
        }
    
        /**
         * 正则匹配
         * @param source
         * @param rule
         * @return
         */
        public static Matcher match(String source,String rule){
            Pattern compile = Pattern.compile(rule);
            Matcher matcher = compile.matcher(source);
            if (matcher.find()) {
                return matcher;
            }
            return null;
        }
    
    
        public static String mybitsIds(List<Integer> list, String splits){
            String join = org.apache.commons.lang3.StringUtils.join(list, splits);
            return addAfterAndBefore("(", join, ")");
        }
    
        /**
         * 在string的前后添加字符
         * @param after
         * @param source
         * @param before
         * @return
         */
        public static String addAfterAndBefore(String after,String source,String before){
            StringBuilder stringBuilder = new StringBuilder(after);
            return stringBuilder.append(source).append(before).toString();
        }
    
        /**
         * 两个字符串中间添加字符串
         * @param header
         * @param tail
         * @param middle
         * @return
         */
        public static String addMiddle(String header,String tail,String... middle){
            StringBuilder stringBuilder = new StringBuilder(header);
            for (String s : middle) {
                stringBuilder.append(s);
            }
            return stringBuilder.append(tail).toString();
        }
    
    
        /**
         * 拼接带有参数的url,url后面有?拼接成 &xxx=xxx,没有?拼接?
         * @param url
         * @param param
         * @return
         */
        public static String concatUrl(String url,String... param){
            StringBuilder stringBuilder = new StringBuilder(url);
            String join = String.join("&", param);
            if (url.indexOf("?")!=-1) {
                return stringBuilder.append("&").append(join).toString();
            }else {
                StringBuilder append = stringBuilder.append("?");
                return append.append(join).toString();
            }
        }

     

    展开全文
  • 包括生成doc文档和docx文档。 二、什么是Freemarker? FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户...

    一、 前言

    在实际开发中,经常会遇到根据给定模板生成Word文档的需求。大体操作是维护一份模板,再通过给这份模板中的变量赋予指定的值,最后调用转换接口,实现Word文档的生成。
    本文主要讲述的是通过Freemarker生成Word文档。包括生成doc文档和docx文档。

    二、什么是Freemarker?

    FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

    模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
    FreeMarker 是 免费的, 基于Apache许可证2.0版本发布。
    在这里插入图片描述
    附个链接:Freemarker中文官方参考手册

    三、 生成doc文档

    1、模板维护

    Word 另存为 xml文件,将模板中需要生成值的地方用${变量名} 来替换。替换好后,将文件 重命名 为ftl(如freemarker.ftl)。

    注意事项:直接在Word中替换变量时,后期转成ftl文件变量可能会被拆开。因此此处先将文件另存为xml格式,然后用word文档打开,然后编辑变量,这样可避免这种问题。当然以防万一,编辑完后可以再次校验一下生成的模板是否正确。

    2、模板存放位置

    1)可以存放本地任意位置,如 /users/xymar/docs
    2)存放项目路径(推荐),如放在resources目录的templates文件夹下:
    在这里插入图片描述

    3、实现
    public static void test(String path){
            Map dataMap = new HashMap();
            try {
                dataMap.put("cardId", "666666");
                dataMap.put("patientName", "张三");
                dataMap.put("cardAttachType", "1");
                // Map<String, String> dataMap = new HashMap<>(CardCode.codeMap);
    
                Configuration configuration = new Configuration(new Version("2.3.0"));
                configuration.setDefaultEncoding("utf-8");
    
                //.ftl配置文件所在路径
                //第一种使用相对一个java文件的相对路径
    configuration.setClassForTemplateLoading(FreemarkerUtil.class, "/templates");
    
                //第二种使用绝对路径
    // configuration.setDirectoryForTemplateLoading(new File("/users/xymar/docs"));
    
                //以utf-8的编码读取ftl模板文件
                Template template = configuration.getTemplate("freemarker.ftl", "utf-8");
    
                //输出文档路径及名称
                File outFile = new File(path);
                Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
                    "utf-8"), 10240);
                template.process(dataMap, out);
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    可以根据自己情况替换map的值,也可结合实际将接口进行封装。

    四、生成docx文档及转换成PDF

    有时我们生成的Word文档会需要转换成PDF,这时生成docx格式更方便转换。此处采用docx4j方式生成docx的word。

    1、模板维护

    模板填入变量后(变量命名为${变量名}),将模板复制一份,后缀改为zip。

    2、所需文件(2个)

    拷贝出zip包里word路径下的document.xml文件,这个就是word的主内容文件。
    维护好的模板(docx文件)和拷贝出的document.xml这两个文件是我们所需要用到的两个模板文件,拷贝到项目工程里面去。

    3、依赖
    		<dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.4.3</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.docx4j/docx4j -->
            <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>8.1.6</version>
            </dependency>
            <dependency>
                <groupId>org.docx4j</groupId>
                <artifactId>docx4j-core</artifactId>
                <version>8.1.7</version>
            </dependency>
            <dependency>
                <groupId>org.docx4j</groupId>
                <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
                <version>8.1.7</version>
            </dependency>
    
    4、实现
    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 PdfUtil {
        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 id, String wordPath) {
            String regex=".*(Courier New|Arial|Times New Roman|Comic Sans|Georgia|Impact|Lucida Console|Lucida Sans Unicode|Palatino Linotype|Tahoma|Trebuchet|Verdana|Symbol|Webdings|Wingdings|Wingdings 2|MS Sans Serif|MS Serif).*";
            Date startDate = new Date();
            // String regex = null;
            PhysicalFonts.setRegex(regex);
            String fileKey = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
    
            OutputStream os = null;
            InputStream is = null;
            try {
                is = new FileInputStream(new File(wordPath));
                WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
                Mapper fontMapper = new IdentityPlusMapper();
                
                PhysicalFonts.addPhysicalFonts("SimSun", FreemarkerUtil.class.getResource("/data/simsun.ttc"));
                // fontMapper.put("Helvetica", PhysicalFonts.get("SimSun"));
                fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
                fontMapper.put("宋体 (中文正文)", PhysicalFonts.get("SimSun"));
    
                PhysicalFonts.addPhysicalFonts("Wingdings 2", FreemarkerUtil.class.getResource("/data/Wingdings 2.ttf"));
                fontMapper.put("Wingdings 2", PhysicalFonts.get("Wingdings 2"));
    
                //解决宋体(正文)和宋体(标题)的乱码问题
                PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
                PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
                mlPackage.setFontMapper(fontMapper);
                //输出pdf文件路径和名称
                String fileName = "pdfNoMark_" + System.currentTimeMillis() + ".pdf";
                // String pdfNoMarkPath = System.getProperty("java.io.tmpdir").replaceAll(separator + "$", "") + separator + fileName;
                String pdfNoMarkPath = "/tmp/" + 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 fileKey;
            } 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 "";
        }
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    
    import java.io.*;
    import java.util.Map;
    
    /**
     * 获取freemarker模板字符串
     */
    public class FreeMarkUtils {
        /**
         * 获取模板字符串输入流
         * @param dataMap   参数
         * @param templateName  模板名称
         * @param tempPath  模板路径 classes下的路径 如果  classes/templates  传入 /templates即可
         * @return
         */
        public static ByteArrayInputStream getFreemarkerContentInputStream(Map dataMap, String templateName, String tempPath) {
            ByteArrayInputStream in = null;
    
            try {
                //创建配置实例
                Configuration configuration = new Configuration();
    
                //设置编码
                configuration.setDefaultEncoding("UTF-8");
    
                //ftl模板文件统一放至 com.lun.template 包下面
    //            configuration.setDirectoryForTemplateLoading(new File("D:/idea_workspace/alarm/alarm/src/main/resources/template/"));
                configuration.setClassForTemplateLoading(FreeMarkUtils.class, tempPath);
                //获取模板
                Template template = configuration.getTemplate(templateName);
    
                StringWriter swriter = new StringWriter();
                //生成文件
                template.process(dataMap, swriter);
                String result = swriter.toString();
                in = new ByteArrayInputStream(swriter.toString().getBytes());
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return in;
        }
    }
    

    五、以下是我过程中遇到的问题(欢迎补充):

    1)转换成的pdf是xml文件
    原因:这是因为之前用freemarker生成word的时候是生成doc格式的,是将模板文件保存为xml格式再生成word,所以生成出来的其实是XML文件。即使在生成的时候将文件后缀名改为docx,生成出来的文件也是打不开的。
    解决方案:docx本质上是个压缩包,里面有包含word主要内容的document.xml文件、资源定义文件document.xml.rels、还有页眉页脚文件、图片资源等等,解决思路是替换内容区的document.xml文件。

    2)生成的pdf中文乱码(全是#)
    原因: 模板中的字体不被识别。
    解决方案:维护模板时设置可被识别的字体,如果还是不能识别,可以在网上下载字体,并将字体文件放到项目路径下,同时接口调用时引入一下此文件即可。

    3)生成的pdf特殊符号不识别(全是#)
    原因: word有些特有的符号,如windings 2 等等
    解决方案:如果也遇到不能识别的情况,同样的下载此符号的字体并引入即可。

    4)Word中的特殊字符如何获取
    参考方案:https://www.cnblogs.com/NieXiaoHui/p/7146898.html

    六、参考链接

    https://blog.csdn.net/qq_34908167/article/details/102784375
    https://www.cnblogs.com/zhouyun-yx/p/11211354.html

    展开全文
  • 使用docx4j生成pdf时,宋体(中文正文)类型无法转换成功。如何配置支持宋体(中文正文)类型字体?转换结果为:代码:String tempPath = "G:\\TestDoc\\weituo2.docx";WordprocessingMLPackage wordMLPackage = ...

    使用docx4j生成pdf时,宋体(中文正文)类型无法转换成功。如何配置支持宋体(中文正文)类型字体?

    eed7fdacb2e95f9407e1d354addaccb8.png

    转换结果为:

    2545ce4f25c976be705f39a9f0582789.png

    代码:

    String tempPath = "G:\\TestDoc\\weituo2.docx";

    WordprocessingMLPackage wordMLPackage = DocxUtils.getWordMLPackage(tempPath);

    String outpath = "G:\\TestDoc\\业务委托单.pdf";

    DocxUtils.toPDF(wordMLPackage,outpath);

    public static void toPDF(WordprocessingMLPackage wordMLPackage,String outPath) throws Exception{

    // Mapper fontMapper = new IdentityPlusMapper();

    Mapper fontMapper = new IdentityPlusMapper();

    wordMLPackage.setFontMapper(fontMapper);

    // PhysicalFont font = PhysicalFonts.getPhysicalFonts().get("Arial Unicode MS");

    // if (font!=null) {

    // fontMapper.getFontMappings().put("Times New Roman", font);

    // }

    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"));

    DocxUtils.toP(wordMLPackage,outPath);

    }

    public static void toP(WordprocessingMLPackage wordMLPackage,String outPath) throws Exception{

    OutputStream os = new FileOutputStream(outPath);

    FOSettings foSettings = Docx4J.createFOSettings();

    foSettings.setWmlPackage(wordMLPackage);

    Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

    }

    展开全文
  • org.docx4j.convert.out.pdf.PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion( wordMLPackage); //注释 org.docx4j.convert.out.pdf.viaXSLFO.Conversion.log.setLevel(Level....

    public class App {

    public static void main(String[] args) {

    try {

    long start = System.currentTimeMillis();

    InputStream is = new FileInputStream(new File("D:\\test.doc"));

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(is);

    /* List sections = wordMLPackage.getDocumentModel().getSections();

    for (int i = 0; i 

    wordMLPackage.getDocumentModel().getSections().get(i).getPageDimensions().setHeaderExtent(3000);

    }*/

    Mapper fontMapper = new IdentityPlusMapper();

    PhysicalFont font = PhysicalFonts.getPhysicalFonts().get("Arial Unicode MS");

    fontMapper.getFontMappings().put("Algerian", font);

    wordMLPackage.setFontMapper(fontMapper);

    PdfSettings pdfSettings = new PdfSettings();

    org.docx4j.convert.out.pdf.PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(

    wordMLPackage);

    //注释

    org.docx4j.convert.out.pdf.viaXSLFO.Conversion.log.setLevel(Level.OFF);

    OutputStream out = new FileOutputStream(new File("D:\\javadomain.pdf"));

    conversion.output(out, pdfSettings);

    System.err.println("Time taken to Generate pdf  " + (System.currentTimeMillis() - start) + "ms");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    //感谢大家阅读本教程,更多精彩内容请持续关注我们!

    展开全文
  • docx4j word转pdf 中文宋体(中文正文)类型转换乱码使用docx4j生成pdf时,宋体(中文正文)类型无法转换成功。如何配置支持宋体(中文正文)类型字体?转换结果为:代码:String tempPath = "G:\\TestDoc\\weituo2.docx";...
  • docx4j 是个非常好用的docx操作包,我主要用来做docx转pdf,但是发现中文会有乱码,原因是因为word里面的中文字体名也是中文的,但是从本地字体库里面拿到的字体名是英文的,所以需要做个映射,这里注意如果是Linux...
  • 1、使用freemaker对模板解析填充数据导出word文档的功能 2、实现使用itext对word转pdf功能 3、实现了对pdf加水印功能
  • 1. 集成步骤引入相关依赖 args4jargs4j2.32org.docx4jdocx4j3.2.1fr.opensagres.xdocreportorg.apache.poi.xwpf.converter.pdf1.0.6fr.opensagres.xdocreportorg.odftoolkit.odfdom.converter.pdf1.0.6...
  • 使用docx4j生成pdf时,宋体(中文正文)类型无法转换成功。如何配置支持宋体(中文正文)类型字体?转换结果为:代码:String tempPath = "G:\\TestDoc\\weituo2.docx";WordprocessingMLPackage wordMLPackage = ...
  • docx4j操作word

    2017-12-19 09:02:12
    docx4j操作word,主要使用docx4jword进行操作,比如chart图表、标签替换、目录等。
  • org.docx4j.convert.out.pdf.PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion( wordMLPackage); //注释 org.docx4j.convert.out.pdf.viaXSLFO.Conversion.log.setLevel(Level....
  • 在分析阶段发现docx4j(http://www.docx4java.org/trac/docx4j)提供了转换功能。在调试开发时遇到了 HTML 格式兼容,样式丢失,PDF 中文字体等问题。二、分析docx4j-ImportXHTML...
  • docx4j实现word文件转换pdf文件

    千次阅读 2020-10-26 17:26:22
    目录前言PDF文件导出通过生成的word文件生成pdf 前言 前段时间在项目中遇到了导出pdf的问题,之前在项目中遇到导出文件莫非就是excle或者是word文件的导出,所以在遇到需要导出pdf文件时,我搜索了许多的网页内容,...
  • 最近做一个租房系统,需要在线生成合同预览,用word模板参数加载真实参数后转PDF发现中文乱码,排查发现只有在word转pdf文件的时候才乱码 解决思路 常规思路: 先从代码层处理,在转PDF的时候配置一些常用字体 ...
  • org.docx4j.convert.out.pdf.PdfConversion c = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage); //清除pdf页码额外调试信息 Docx4jProperties.getProperties().setProperty("docx4j.Log4j....
  • org.docx4j.convert.out.pdf.PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion( wordMLPackage); //注释生成pdf 默认的内容 org.docx4j.convert.out.pdf.viaXSLFO.Conversion....
  • 生成的word是这样的 转换为pdf是这样的 想请教一下怎么解决,代码如下
  • docx4j生成word之后pdf

    千次阅读 2017-06-16 09:53:14
    所需Jar包 (注意,jar不能少,版本也要对应,否则会报错,类似:org/plutext/jaxb/xslfo/ObjectFactory 这样的错误都是因为缺少jar包) ...docx4j-2.7.1  log4j-1.2.15  serializer-2.7.1  xmlgraphics-commons-
  • 本文参考文章如下 在这里插入代码片 java转pdf(html转为pdf)...docx4j word转pdf 中文宋体(中文正文)类型转换乱码 java实现html转pdf,支持中文,css以及中文换行 java项目实现html转pdf的需求(支持中文和CSS样...
  • docx4j优势: 免费开源可商用,服务器无需安装office软件等 docx4j劣势: 性能效率相对于其他框架而言较差 复杂的word排版内容可能无法转换,对格式要求较高 适用场景: 对性能效率要求不高,word内容排版简单,后续...
  • 直接用java代码进行 word 转pdf ,测试没有问题 docx4j 依赖的库: &lt;dependency&gt; &lt;groupId&gt;args4j&lt;/groupId&gt; &lt;artifactId&gt;args4j&lt;/artifactId&...
  • 如题,通过docx4j这个框架解析项目下的docx模板,然后在数据库查询数据,填充到Map,然后替换模板中的占位符${name},生成一个新的docx文档,并生成pdf文件。 1.jar包依赖 <dependency> <groupId>org....
  • docx4j在linux系统进行word转pdf乱码,都是#号,该如何解决 这是主要代码 WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is); Mapper fontMapper = new IdentityPlusMapper(); URL fontUrl= ...
  • Docx4jWord转PDF及HTML的实现

    千次阅读 2015-05-05 17:26:13
    最近在研究Web中的文档管理,文档管理永远是企业中的很重要的一部分,其中遇到一最大的难题就是如何实现把大部分常用的文档进行在线预览及搜索,如果仅是实现Doc的展示,问题比较简单,JAVA中对Word的操作比较多。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,208
精华内容 883
关键字:

docx4jword转pdf

友情链接: Batch_fft.zip