java dox4j实现word转pdf


前言

图片、word转pdf文档方法


代码如下(示例):

	/**
	 * 图片、word转pdf
	 *
	 * @param fileType     文件类型
	 * @param sourcePath   文件网络路径
	 * @param saveFileName 文件保存名字
	 * @param folderName   文件保存根目录
	 */
	public void convertToPdf(String fileType, String sourcePath, String saveFileName, String folderName) {
		String fileSavePath = saveFileToLocal(sourcePath, saveFileName, folderName);
		File file = null;
		// 生成随机文件名
		String pdfFileName = UUID.randomUUID().toString().replace("-", "") + ".pdf";
		if (StringUtils.equalsIgnoreCase(fileType, ".doc") || StringUtils.equalsIgnoreCase(fileType, ".docx")) {
			// word文件转成PDF文件
			file = wordToPdf(fileSavePath + saveFileName, fileSavePath + pdfFileName);
		} else if (StringUtils.equalsIgnoreCase(fileType, ".jpg") || StringUtils.equalsIgnoreCase(fileType, ".jpeg") || StringUtils.equalsIgnoreCase(fileType, ".png")) {
			// 图片文件转成PDF文件
			file = imageToPdf(new File(fileSavePath + saveFileName), fileSavePath + pdfFileName);
		} else if (StringUtils.equalsIgnoreCase(fileType, ".pdf")) {
			file = new File(fileSavePath + saveFileName);
		} else {
			throw new ServiceException("文件无效");
		}
		if (file == null) {
			throw new ServiceException("文件转换失败");
		}
		// 删除临时生成的文件夹及其子文件夹和子文件
		deleteDirectory(new File(fileSavePath));
	}

	/**
	 * word转pdf
	 *
	 * @param source 源文件路径
	 * @param target 生成文件目标路径
	 * @return pdf文本
	 */
	public static File wordToPdf(String source, String target) {
		try {
			WordprocessingMLPackage pkg = Docx4J.load(new File(source));

			Mapper fontMapper = new IdentityPlusMapper();

			//解决宋体(正文)和宋体(标题)的乱码问题
			PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("仿宋", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("黑体", PhysicalFonts.get("SimSun"));
			PhysicalFonts.put("等线", PhysicalFonts.get("SimSun"));

			//将字体替换为服务器中存在的字体
			fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
			fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
			fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
			fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
			fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
			fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
			fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
			fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
			fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
			fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
			fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
			fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
			fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
			fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
			fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
			fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
			fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
			fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
			fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
			fontMapper.put("仿宋_GB2312", PhysicalFonts.get("STFangsong"));
			fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));

			PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
			fontMapper.put("SimSun", simsunFont);
			//设置字体
			pkg.setFontMapper(fontMapper);

			Docx4J.toPDF(pkg, new FileOutputStream(target));
			return new File(target);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("word转pdf失败!");
		}
		return null;
	}

	/**
	 * 图片转pdf
	 *
	 * @param imageFile 图片文件
	 * @param retFile 输出的pdf文件
	 * @return
	 */
	public static File imageToPdf(File imageFile, String retFile) {
		try {
			MultipartFile multipartFile = getMultipartFile(imageFile);
			Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
			PdfWriter.getInstance(doc, new FileOutputStream(retFile));
			doc.open();
			doc.newPage();
			Image image = Image.getInstance(multipartFile.getBytes());
			float height = image.getHeight();
			float width = image.getWidth();
			int percent = getPercent(height, width);
			image.setAlignment(Image.MIDDLE);
			image.scalePercent(percent);
			doc.add(image);
			doc.close();
			File pdfFile = new File(retFile);
			return pdfFile;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("图片转pdf失败!");
		}
		return null;
	}

	/**
	 * 获取图片对比A4纸的比例
	 *
	 * @param height 高度
	 * @param weight 宽度
	 * @return 比例
	 */
	private static int getPercent(float height, float weight) {
		float percent = 0.0F;
		if (height > weight) {
			percent = PageSize.A4.getHeight() / height * 100;
		} else {
			percent = PageSize.A4.getWidth() / weight * 100;
		}
		return Math.round(percent);
	}

	public static MultipartFile getMultipartFile(File file) {
		FileItem item = new DiskFileItemFactory().createItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName());
		try (InputStream input = new FileInputStream(file);
			 OutputStream os = item.getOutputStream()) {
			// 流转移
			IOUtils.copy(input, os);
		} catch (Exception e) {
			throw new IllegalArgumentException("Invalid file: " + e, e);
		}
		return new CommonsMultipartFile(item);
	}
	
	/**
	 * 将文件保存至本地
	 *
	 * @param filePath     原始文件路径
	 * @param saveFileName 文件保存父文件夹
	 * @param saveFolder   文件保存根文件夹
	 * @return
	 */
	private String saveFileToLocal(String filePath, String saveFileName, String saveFolder) {
		log.info("saveFileToLocal方法开始. ");
		FileOutputStream outputStream = null;
		InputStream inputStream = null;
		try {
			HttpURLConnection httpUrl = (HttpURLConnection) new URL(filePath).openConnection();
			httpUrl.connect();
			inputStream = httpUrl.getInputStream();

			// 根据时间戳创建文件
			String dateFolderName = System.currentTimeMillis() + "/";
			log.info("时间戳创建文件: {}. ", dateFolderName);
			File file = new File(saveFolder + dateFolderName);
			log.info("时间戳创建文件对象: {}. ", file);
			if (!file.exists()) {
				log.info("准备创建文件夹. ");
				file.mkdirs();// 如果不存在,创建目录
				log.info("成功创建文件夹. ");
			}
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			log.info("准备输出文件. ");
			while ((len = inputStream.read(buffer)) != -1) {
				outStream.write(buffer, 0, len);
			}
			File outFile = new File(saveFolder + dateFolderName + saveFileName);
			FileOutputStream fops = new FileOutputStream(outFile);
			fops.write(outStream.toByteArray());
			log.info("输出文件完成. ");
			fops.flush();

			return saveFolder + dateFolderName;
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
				}
			}
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
				}
			}
		}
	}
	/**
	 * 删除文件夹及其子文件夹和子文件
	 *
	 * @param dir 待删除文件夹
	 * @return
	 */
	public static boolean deleteDirectory(File dir) {
		if (dir.isDirectory()) {
			File[] subFiles = dir.listFiles();

			for (int i = 0; i < subFiles.length; i++) {
				boolean success = deleteDirectory(subFiles[i]);
				if (!success) {
					return false;
				}
			}
		}
		return dir.delete();
	}

注:

  1. word转pdf容易乱码,需要在容器中安装字体,如果容器中没有,要将word中的字体替换成容器中有的
	WordprocessingMLPackage pkg = Docx4J.load(new File(source));
	Mapper fontMapper = new IdentityPlusMapper();
	// 将仿宋_GB2312替换为仿宋
	fontMapper.put("仿宋_GB2312", PhysicalFonts.get("STFangsong"));
	pkg.setFontMapper(fontMapper);
  1. word转pdf仅支持docx格式,不支持doc格式
  2. 如果运行环境不是linux,推荐使用documents4j做word转pdf,方便且效率高
		<dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-local</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-transformer-msoffice-word</artifactId>
            <version>1.1.1</version>
        </dependency>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值