pdf相关工具类(包括docx转pdf,pdf转图片,pdf添加水印)

标签: 工具
12人阅读 评论(0) 收藏 举报

pdf相关工具类(包括docx转pdf,pdf转图片,pdf添加水印)

最近做项目遇到很多关于pdf的一些需求,在整个过程中遇到了很多问题,在这总结一些我遇到的一些问题和一些坑,并且把整理出来并且测试过的工具类发出来,工具类中可能有很多判断没有做,如果有人需要,请自己完善把。

docx转pdf(注意:是docx)

首先注意一下是docx转pdf,本文主要写的是docx转pdf,暂时只支持docx,千万不要尝试doc改个后缀名就可以用了,并不是的,你可以试下,真的不可以,但是也不是说不可以做到doc转pdf,只是转换的时候需要有应用程序,效率上不是很高,而且很麻烦,不如在需求上做个限制,给产品经理买盒烟把。下面还有几个点需要注意一下;

  • 更新一下本地的字体库,因为工具是依赖本地的字体库的
  • 如果你要上传到服务器上,你要记得把windows下的字体库复制一份到linux下;windows字体在这个路径下: C:\WINDOWS\Fonts, linux下的字体库在这个路径下: /usr/share/fonts;复制好了别忘了敲几行命令把字体生效:
    – mkfontscale
    – mkfontdir
    – fc-cache -fv
pdf转image
  • 没什么特别需要注意的,还是字体库,一定要把字体库弄全!尤其是到linux下,一定要字体库复制过去并生效!

pdf添加水印

这个确实有点恶心,这个依赖的jar包是itext2.1.7的jar包,它所引用的水印字体的配置,并不在jar包内,我查了一下资料,才发现,添加水印时候一定要依赖另一个jar包,我觉得像是一个补丁:iTextAsian.jar,我从maven下载了jar包,并引用,发现并没有什么用,我又找了很多资料,发现这个补丁的包结构和itext的结构不一样,需要修改包结构,终于找到问题,修改一下包结构就ok了,后续会把修改后的jar包贴出来,直接下载引用就好,注意一下jar包版本,由于我用的gradle不是maven,所以贴出来的是gradle地址,不过都是一样的,转一下就好;

工具需要的jar包地址

compile group: 'com.lowagie', name: 'itext', version: '2.1.7'
compile fileTree(dir:'libs', include:['*.jar'])
compile 'org.apache.pdfbox:fontbox:2.0.1'
compile 'org.apache.pdfbox:pdfbox:2.0.1'
compile group: 'fr.opensagres.xdocreport', name: 'org.apache.poi.xwpf.converter.pdf', version: '1.0.4'

iTextAsian.jar 下载地址: https://pan.baidu.com/s/1n6SzXd851_BC-LzWH9BQIA

工具类代码

import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.*;
import fr.opensagres.xdocreport.utils.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author JiShaochen
 * @date 2018/4/14 16:03
 * @desc .
 */
public class PDFUtils {

    public static void main(String[] args){
//        pdfConvertToImage("D:/1.pdf", "D://2");
        try {
//            docConvertToPdf("D:/1.docx", "D:/2.pdf");
            pdfToWatermarkPdf("D:/1.pdf", "D:/3.pdf", "水印文字");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * @Author: ShaoChen
     * @Description: PDF转为多张图片 sourcePath是源文件, targetSource是
     * @Date: 16:07 2018/4/14
     */
    public static Integer pdfConvertToImage(String sourcePath, String targetSource) {
        File file = new File(sourcePath);
        try {
            file.mkdir();
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for(int i=0; i<pageCount; i++){
                BufferedImage image = renderer.renderImage(i, 2.5f);
                ImageIO.write(image,"JPG",new File(targetSource+ "/" + i + ".jpg"));
            }
            return pageCount;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * @Author: ShaoChen
     * @Description: 将docx文件转换为Pdf文件, 调用这个方法,后面的配合使用的
     * @Date: 10:30 2018/4/16
     */
    public static void docConvertToPdf(String docxPath, String targetUrl) throws Exception {
        InputStream source = new FileInputStream(docxPath);
        OutputStream target = new FileOutputStream(targetUrl);
        Map<String, String> params = new HashMap<String, String>();
        PdfOptions options = PdfOptions.create();
        wordConverterToPdf(source, target, options, params);
    }

    /**
     * 将word文档, 转换成pdf, 中间替换掉变量
     *
     * @param source 源为word文档, 必须为docx文档
     * @param target 目标输出
     * @param params 需要替换的变量
     * @throws Exception
     */
    public static void wordConverterToPdf(InputStream source,
                                          OutputStream target, Map<String, String> params) throws Exception {
        wordConverterToPdf(source, target, null, params);
    }

    /**
     * 将word文档, 转换成pdf, 中间替换掉变量
     *
     * @param source  源为word文档, 必须为docx文档
     * @param target  目标输出
     * @param params  需要替换的变量
     * @param options PdfOptions.create().fontEncoding( "windows-1250" ) 或者其他
     * @throws Exception
     */
    public static void wordConverterToPdf(InputStream source, OutputStream target,
                                          PdfOptions options,
                                          Map<String, String> params) throws Exception {
        XWPFDocument doc = new XWPFDocument(source);
        paragraphReplace(doc.getParagraphs(), params);
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    paragraphReplace(cell.getParagraphs(), params);
                }
            }
        }
        PdfConverter.getInstance().convert(doc, target, options);
    }

    /**
     * 替换段落中内容
     */
    private static void paragraphReplace(List<XWPFParagraph> paragraphs, Map<String, String> params) {
        if (!params.isEmpty()) {
            for (XWPFParagraph p : paragraphs) {
                for (XWPFRun r : p.getRuns()) {
                    String content = r.getText(r.getTextPosition());
                    if (StringUtils.isNotEmpty(content) && params.containsKey(content)) {
                        r.setText(params.get(content), 0);
                    }
                }
            }
        }
    }

    /**
     * @Author: ShaoChen
     * @Description:   pdf添加水印
     * @Date: 10:36 2018/4/16
     */
    public static void pdfToWatermarkPdf(String sourceUrl, String targetUrl, String message) throws IOException, DocumentException {
        // 要输出的pdf文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(targetUrl)));
        // 将pdf文件先加水印然后输出
        setWatermark(bos, sourceUrl, 16, message);
    }

    public static void setWatermark(BufferedOutputStream bos, String input,
                                    int permission, String message) throws DocumentException,
            IOException {

        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, bos);
        int total = reader.getNumberOfPages() + 1;
        BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.EMBEDDED);
        PdfGState gs = new PdfGState();
        for (int i = 1; i < total; i++) {
            /*
               首先介绍一下: 前两个参数是pdf的横纵坐标,可以想象成一个平面直角坐标系,原地在pdf每页的左下角;
               line为x轴;
               height为y轴;
               angle为水印的角度;
               这三个参数自己调整就好
            */
            // 设置第一行水印
            setLineWaterMark(stamper, base, gs, i, 140,1000, 40, message);
            setLineWaterMark(stamper, base, gs, i, 320,1000, 40, message);
            setLineWaterMark(stamper, base, gs, i, 500,1000, 40, message);
            setLineWaterMark(stamper, base, gs, i, 680,1000, 40, message);
            setLineWaterMark(stamper, base, gs, i, 860,1000, 40, message);
            // 设置第二行水印
            setLineWaterMark(stamper, base, gs, i, 140,700, 40, message);
            setLineWaterMark(stamper, base, gs, i, 320,700, 40, message);
            setLineWaterMark(stamper, base, gs, i, 500,700, 40, message);
            setLineWaterMark(stamper, base, gs, i, 680,700, 40, message);
            setLineWaterMark(stamper, base, gs, i, 860,700, 40, message);
            // 设置第三行水印
            setLineWaterMark(stamper, base, gs, i, 140,400, 40, message);
            setLineWaterMark(stamper, base, gs, i, 320,400, 40, message);
            setLineWaterMark(stamper, base, gs, i, 500,400, 40, message);
            setLineWaterMark(stamper, base, gs, i, 680,400, 40, message);
            setLineWaterMark(stamper, base, gs, i, 860,400, 40, message);
            // 设置第四行水印
            setLineWaterMark(stamper, base, gs, i, 140,100, 40, message);
            setLineWaterMark(stamper, base, gs, i, 320,100, 40, message);
            setLineWaterMark(stamper, base, gs, i, 500,100, 40, message);
            setLineWaterMark(stamper, base, gs, i, 680,100, 40, message);
            setLineWaterMark(stamper, base, gs, i, 860,100, 40, message);

        }
        stamper.close();
    }

    private static void setLineWaterMark(PdfStamper stamper, BaseFont base, PdfGState gs, int page, Integer line,
                                         Integer height, Integer angle, String message) {
        PdfContentByte content;
        content = stamper.getOverContent(page);// 在内容上方加水印
//                content = stamper.getUnderContent(i);//在内容下方加水印
        gs.setFillOpacity(0.2f);
        content.setGState(gs);
        content.beginText();
        content.setColorFill(Color.LIGHT_GRAY);
        content.setFontAndSize(base, 16);
        content.setTextMatrix(20, 70);
        content.showTextAligned(Element.ALIGN_CENTER, message, line, height, angle);
        content.setColorFill(Color.BLACK);
        content.setFontAndSize(base, 8);
        content.endText();
    }
}
查看评论

java将pdf,word,excel转成图片

java将pdf,word,excel转成图片 一.说明      pdf转化成图片有几种方式,这里介绍两种,一种通过PDFRenderer的支持转化为图片,这种方式最终没有采取,实际使用中发现高版本...
  • qq_27063119
  • qq_27063119
  • 2017年03月16日 15:38
  • 7737

OpenOffice将MS docx转换成pdf文件偶数页眉不显示问题解决办法

OpenOffice版本:4.0(Windows、Linux下测试都出现问题) MS Office版本:2007 问题描述 使用OpenOffice将MS的docx文件转换为pdf文件时,doc...
  • mycdsnstudy
  • mycdsnstudy
  • 2015年04月24日 15:24
  • 1126

java实现将txt文件转为pdf加密并加水印

package com.flexpaper; import java.io.*; import com.lowagie.text.*; import com.lowagie.te...
  • YBabyRjm
  • YBabyRjm
  • 2014年01月15日 16:41
  • 1244

带水印PDF转Word软件转换效果对比

在日常办公中经常需要接触到PDF和Word这两种常用格式,为了方便保存和安全需要,可以将Word转换成PDF格式,为了方便编辑修改这时我们需要将PDF转换成Word,不过,在PDF转Word的过程中经...
  • qq_40121517
  • qq_40121517
  • 2017年09月11日 18:19
  • 337

使用Aspose.Pdf将指定PDF也转换为PNG图片

概述:Png Device类允许将PDF页转换为Png图像。这个类提供了一个叫Process方法用来实现这一转换过程。您首先需要创建一个文档类对象,用于获取需要转换成PNG格式的指定PDF页。之后,调...
  • fengkuangdianji
  • fengkuangdianji
  • 2013年04月12日 14:00
  • 674

如何word转换成pdf文件,怎样添加水印?

word文档在传输给其他人查看时往往需要转成pdf文件,这样可以使得文件在任何系统下都可以打开查看,还能使文档内容不会被随意改动,有时还需要为转换的pdf文件添加上水印等,那么这些操作怎样去实现,怎样...
  • nameina
  • nameina
  • 2016年10月25日 13:49
  • 793

利用openoffice将doc、docx转为pdf

1. 需要用的软件    OpenOffice   ,  JodConverter  2.启动OpenOffice的服务     我到网上查如何利用OpenOffice进行转码的时候...
  • freewindgo
  • freewindgo
  • 2017年01月23日 13:42
  • 2237

docx文档转pdf文件

注:这里只能转换docx文件,doc不行,源码在文末。 可以在windows,linux上运行,增加了内容替换功能,因为有些文档内容需要我们用代码来动态生成。 下面是具体操作步骤: maven...
  • thc1987
  • thc1987
  • 2018年01月26日 12:41
  • 128

Java读写pdf、pdf转图片工具类

本工具类所用到的相关jar包及版本有:     1.pdfbox-1.5.0.jar     2.fontbox-1.5.0.jar     3.jempbox-1.5.0.jar     4...
  • Flood_Dragon
  • Flood_Dragon
  • 2012年10月31日 17:41
  • 1964

【Java】中常用的几种 DOCX 转 PDF 方法

DOCX2PDF 将DOCX文档转化为PDF是项目中常见的需求之一,目前主流的方法可以分为两大类,一类是利用各种Office应用进行转换,譬如Microsoft Office、WPS以及Libe...
  • hj7jay
  • hj7jay
  • 2016年09月02日 22:38
  • 4156
    个人资料
    等级:
    访问量: 0
    积分: 22
    排名: 0
    文章分类
    文章存档