天天看点

java处理pdf文件——iText的使用

       PDF(Portable Document Format的简称,意为“便携式文档格式”),是由Adobe Systems用于与应用程序、操作系统、硬件无关的方式进行文件交换所发展出的文件格式。PDF文件以PostScript语言图象模型为基础,无论在哪种打印机上都可保证精确的颜色和准确的打印效果,即PDF会忠实地再现原稿的每一个字符、颜色以及图象。(来自百度百科的介绍)。

     可以用来处理pdf文件的第三方jar包主要有Apache PDFBox,iText (收费,功能更强大,功能更全面,最新版本itext7),XDocReport (将docx转化为pdf,需要借助poi和itext).

Apache PDFBox中的主要功能:创建文本,提取文本,合并文档,分割文档,删除页面等。

java处理pdf文件——iText的使用

官网最新版是2.0.19

java处理pdf文件——iText的使用

写了一个测试类,pdfbox非常不好用,在设置字体时,用的是内置常量,运行代码debug发现查找本地字体需要耗费很长时间,还有就是写入文档的时候,时间太久了,非常不好用,而且jar包中的字体类,内置的字体没有支持中文的字体,对中文不友好,不推荐使用。

这是测试类:(可以看一下)

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2020/5/3 15:11
 */

public class ApachePDFBoxTest {
    @Test
    public void createPdfFileTest(){

//        创建文档页面(设置为矩形A4大小)
        PDPage page = new PDPage(PDRectangle.A4);

//        创建pdf文档对象,以及页面内容流对象
        try ( PDDocument pdfDocument=new PDDocument();PDPageContentStream pageContentStream=new PDPageContentStream(pdfDocument,page)){
            pdfDocument.addPage(page);
//        设置字体为Helvetica-Bold或TIMES_ROMAN;,类库中没有中文字体,程序会去查找本地是否安装了该字体,查找非常慢
            PDFont font= PDType1Font.TIMES_ROMAN;
//            开始页面的文本操作
            pageContentStream.beginText();
            pageContentStream.setFont(font,12);
            pageContentStream.moveTextPositionByAmount(100,700);
//            因为jar包中自带的没有中文字体,所以写入中文会出异常
            pageContentStream.showText("hello");

//            结束页面文本操作
            pageContentStream.endText();
//            pdf文档保存在本项目所在磁盘下data目录下
            File pdfFile=new File("E:"+File.separator+"data"+File.separator +"test.pdf");
//            保存pdf文档,写入非常慢!!测试了一下,写了一句hello,保存用了十几分钟,不知道为什么
            pdfDocument.save(pdfFile);
            System.out.println("文件写入成功");

        } catch (IOException e) {
            e.printStackTrace();
        }finally{
//            流虽然都关闭了,但是还是无法删除文件,所以手动调用一下gc
            System.gc();
            System.out.println("执行垃圾回收");
        }



    }
}
           

写入到文件非常慢(即执行save方法时),不推荐使用pdfbox.

处理pdf文件首推itext,使用7.1.8版本,导入jar包时候,选择itext-core这个jar包(最新版就是7.x系列),在idea中输入itext还会显示一个itextpdf,这个jar包还是5.x系列版本(属于旧版本)

java处理pdf文件——iText的使用
<!--推荐使用itext处理pdf文档-->
    <dependency>
      <groupId>com.itextpdf</groupId>
      <artifactId>itext7-core</artifactId>
      <version>7.1.8</version>
    </dependency>
           

itext7-core包含了很多jar包,其中也包含了font-asian(可以用来处理中文字体)

font-asian.jar里面是有两种文件,展开cmap包,一种是cmap文件(编码文件),另一种是.properties文件(与字体程序有关)

java处理pdf文件——iText的使用
java处理pdf文件——iText的使用

设置中文字体时,还可以用window中已安装的字体,给出字体路径,每个字体的名称可以右键查看属性

import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.DeviceGray;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.property.VerticalAlignment;
import com.xiaomifeng1010.beanutils.bean.Person;
import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * 使用itext操作pdf文档,在pdf中创建一个表格,将person属性存放到表格中。
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2020/5/3 19:49
 */

public class ITextTest {
//    保存文件的路径(当前项目所在磁盘下data目录下,pdf目录下的simple_table.pdf文件)
    public  String filePath=File.separator +"data"+File.separator+"pdf"+File.separator +"simple_table.pdf";
//    创建文件
    File file=new File(filePath);

    /**
     * 测试在pdf中写入一个表格
     */
    @Test
    public void createPdfFileTest() {
        if (!file.exists()) {
            file.getParentFile().mkdirs();
        }
        try {
//            设置字体为HELVETICA(不支持中文)
//            PdfFont pdfFont= PdfFontFactory.createFont(StandardFonts.HELVETICA);
//            设置中文字体为黑体常规(传入一个字体路径或者itext中内置支持的字体,如上)
            PdfFont documentFont=PdfFontFactory.createFont("C:\\Windows\\Fonts\\simhei.ttf", PdfEncodings.IDENTITY_H,true);
//            使用font-asian中的字体,设置字体华文宋体(STSong-Light)
            PdfFont tableFont=PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H",true);
            PdfDocument pdfDocument=new PdfDocument(new PdfWriter(filePath));
            Document document=new Document(pdfDocument);
//            设置文本居中对齐
            document.setTextAlignment(TextAlignment.CENTER);
            document.setHorizontalAlignment(HorizontalAlignment.CENTER);
//            设置文档字体
            document.setFont(documentFont);
//            表格标题
            Paragraph tableTitle=new Paragraph("人员信息表");
//            设置表格标题字体和颜色(段落)
            tableTitle.setFont(documentFont).setFontColor(DeviceGray.BLACK);
            document.add(tableTitle);
            Table table=new Table(UnitValue.createPercentArray(3)).useAllAvailableWidth();
//            设置表格字体
            table.setFont(tableFont);
//            设置表格列宽
            table.setWidth(200);
//            设置表格背景色
            table.setBackgroundColor(ColorConstants.LIGHT_GRAY);
//            设置表格文本居中对齐
            table.setTextAlignment(TextAlignment.CENTER);
//            设置表格垂直对齐方式
            table.setVerticalAlignment(VerticalAlignment.MIDDLE);
//            设置表格水平对齐方式
            table.setHorizontalAlignment(HorizontalAlignment.CENTER);
//            Cell cell=new Cell();
//            设置单元格背景色为深灰色
//            cell.setBackgroundColor(ColorConstants.DARK_GRAY);
            List<Person> persons=new ArrayList<>();
            persons.add(new Person(12,"Albert","male"));
            persons.add(new Person(15,"Johnson","male"));
            persons.add(new Person(22,"Larry","female"));
            table.addCell(new Paragraph("姓名"));
            table.addCell(new Paragraph("年龄"));
            table.addCell(new Paragraph("性别"));

            for (Person person :
                    persons) {
//                更精确的颜色可以使用new DeviceRgb()传入三原色的数值[0-255]来设置
//                new DeviceRgb(13,23,5);
                table.addCell(new Paragraph(person.getName()).setFontColor(DeviceRgb.RED));
                table.addCell(new Paragraph(String.valueOf(person.getAge())).setFontColor(DeviceRgb.GREEN));
                table.addCell(new Paragraph(person.getGender()).setFontColor(DeviceRgb.BLUE));
            }
            document.add(table);
            document.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

最终创建好的pdf文档:

java处理pdf文件——iText的使用

打开文档查看具体效果:

java处理pdf文件——iText的使用

itext官网中还提供了更多关于pdf的操作,具体可以参考官网示例: https://itextpdf.com/en/resources/examples