Java将PDF输出为Excel

前段时间应需求写了一个将PDF输出为Excel的小程序,希望通过这篇博客给有同样需求的人一些思路。
首先用到的语言是Java,其中引入了一些对PDF和Excel进行操作的包,主要思路就是先将PDF输出为txt文件,然后再爬取txt中的关键字和数据,输出到Excel中。

下载PDFBox包

pdfbox-2.0.3.jar:http://apache.fayea.com/pdfbox/2.0.3/pdfbox-2.0.3.jar
(满足一般的PDF操作需求)
pdfbox-app-2.0.3.jar:http://apache.fayea.com/pdfbox/2.0.3/pdfbox-app-2.0.3.jar
(PDFbox的多个命令行的工具包)
fontbox-2.0.3.jar:http://apache.fayea.com/pdfbox/2.0.3/fontbox-2.0.3.jar
(PDF使用的字库包)

*为了方便一些对eclipse操作不熟练的同学,我简要介绍一下如何引入所需要的依赖包,大神可跳过。
右键项目->Build Path->Configure Build Path…->Add External JARs…
然后将你下好的jar包引入就可以了

话不多说直接上代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

//将pdf文件输出为txt
    public static void PDFtoTXT(File pdf) {
        PDDocument pd;
        BufferedWriter wr;
        try {
            File input = pdf; 
            // The PDF file from where
            // you would like to
            // extract
            File output = new File(pdf.getName().split("\\.")[0] + ".txt");
            // The text file where
            // you are going to
            // store the
            // extracted data
            pd = PDDocument.load(input);
            pd.save("CopyOf" + pdf.getName().split("\\.")[0] + ".pdf"); // Creates a copy called
            // "CopyOfInvoice.pdf"
            PDFTextStripper stripper = new PDFTextStripper();
            wr = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(output)));
            stripper.writeText(pd, wr);
            if (pd != null) {
                pd.close();
            }
            // I use close() to flush the stream.
            wr.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

上述方法实现了将PDF文件输出为txt文件的功能

下面我们考虑如何从txt文件中抓出想要的关键字并输出到Excel中
这里需要引入另一个依赖包,这里可以选择的有jxl和POI
简要分析jxl和poi的优缺点:(数据来源:http://blog.csdn.net/jarvis_java/article/details/4924099

1、jxl

优点:
    -Jxl对中文支持非常好,操作简单,方法看名知意。
    -Jxl是纯javaAPI,在跨平台上表现的非常完美,代码可以再windows或者Linux上运行而无需重新编写
    -支持Excel 95-2000的所有版本(网上说目前可以支持Excel2007了,还没有尝试过)
    -生成Excel 2000标准格式
    -支持字体、数字、日期操作
    -能够修饰单元格属性
    -支持图像和图表,但是这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。
缺点:效率低,图片支持不完善,对格式的支持不如POI强大

2、POI

优点:
    -效率高
    -支持公式,宏,一些企业应用上会非常实用
    -能够修饰单元格属性
    -支持字体、数字、日期操作
缺点:不成熟,代码不能跨平台,貌似不少同行在使用工程中还碰到让人郁闷的BUG(最近的项目中也是遇到了一些bug,不过目前没有查出来是代码的问题还是POI的问题,总之问题很诡异,数据替代参数总有失败的。关于不能跨平台这一说,我也没有试验过,不过Java不是跨平台吗?POI是JAVA的一个组件,怎么就不能跨平台了呢,总之这些问题还需要在以后的项目中多多实践,才能比较出区别之处。)

这里我选择的是jxl,所以以jxl为例

jxl.jar下载地址:

http://jaist.dl.sourceforge.net/project/jexcelapi/jexcelapi/2.6.12/jexcelapi_2_6_12.zip
下载完成后解压里面的jxl.jar
记得在项目中引入包,方法同上

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

//初始化excel
    public static WritableWorkbook wwb = null;
    public static WritableSheet ws;
    public static void initExcel(){
        try {
            //首先要使用Workbook类的工厂方法创建一个可写入的工作薄(Workbook)对象
            wwb = Workbook.createWorkbook(new File("excel.xlsx"));
            if(wwb != null){
                //创建一个可写入的工作表
                //Workbook的createSheet方法有两个参数,第一个是工作表的名称,第二个是工作表在工作薄中的位置
                ws = wwb.createSheet("sheet1", 0);
                //下面开始添加单元格
                //这里需要注意的是,在Excel中,第一个参数表示列,第二个表示行
                ws.addCell(new Label(0, 0, "公司名")); //将生成的单元格添加到工作表中
                ws.addCell(new Label(1, 0, "财报时间"));
                ws.addCell(new Label(2, 0, "创新"));
                ws.addCell(new Label(3, 0, "财政补贴"));
                ws.addCell(new Label(4, 0, "优惠"));
                ws.addCell(new Label(5, 0, "税收优惠"));
                ws.addCell(new Label(6, 0, "递延所得税费用"));
                ws.setColumnView(0, 30);
                ws.setColumnView(1, 10);
                ws.setColumnView(3, 14);
                ws.setColumnView(6, 15);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (RowsExceededException e) {
            e.printStackTrace();
        } catch (WriteException e) {
            e.printStackTrace();
        }
    }

    //爬取目录下的txt文件中关键字并输出到excel文件中
    public static boolean isMain = false;
    public static boolean isYear = false;
    public static String name = null;
    public static String time = null;
    public static void TXTtoEXCEL(File txt) {
        isMain = true;
        isYear = true;
        name = null;
        time = null;
        try {
            BufferedReader br = new BufferedReader(new FileReader(txt));
            System.out.println(txt.getName());
            String line = "";

            while((line = br.readLine()) != null) {
                Pattern p0 = Pattern.compile("\\s*(([()]|[\u4E00-\u9FA5])*(股份有限公司))");
                Matcher m0 = p0.matcher(line);
                if (m0.find() && true == isMain) {
                    System.out.println(line);                   
                    System.out.println("公司名=" + m0.group(1));
                    name = m0.group(1);
                    isMain = false;
                    continue;
                }

                Pattern p1 = Pattern.compile("\\s*(([一二三四五六七八九十〇○]|[0-9])*\\s*年)");
                Matcher m1 = p1.matcher(line);
                if(m1.find() && true == isYear) {
                    System.out.println(line.replaceAll("○", "〇"));
                    System.out.println("财报时间=" + m1.group(1).replaceAll("○", "〇"));
                    time = m1.group(1).replaceAll("○", "〇");
                    isYear = false;
                    continue;
                }

                if(name != null && time != null) {
                    break;
                }

            }

            while((line = br.readLine()) != null) {
                Pattern p2 = Pattern.compile("\\s*(创新)(\\s*)(--\\s)?((-*)(\\d*,)*(\\d*\\.\\d*))");
                Matcher m2 = p2.matcher(line);
                if(m2.find()) {
                    System.out.println(line);
                    System.out.println("创新=" + m2.group(4));
                    System.out.println(count);
                    ws.addCell(new Label(0, count, name));
                    ws.addCell(new Label(1, count, time));
                    ws.addCell(new Label(2, count, m2.group(4)));
                    count ++;
                    continue;
                }

                Pattern p3 = Pattern.compile("\\s*(政府补助|财政补贴)(\\s*)(--\\s)?((-*)(\\d*,)*(\\d*\\.\\d*))");
                Matcher m3 = p3.matcher(line);
                if(m3.find()) {
                    System.out.println(line);
                    System.out.println("政府补贴=" + m3.group(4));
                    System.out.println(count);
                    ws.addCell(new Label(0, count, name));
                    ws.addCell(new Label(1, count, time));
                    ws.addCell(new Label(3, count, m3.group(4)));
                    count ++;
                    continue;
                }

                Pattern p4 = Pattern.compile("\\s*(优惠)(\\s*)(--\\s)?((-*)(\\d*,)*(\\d*\\.\\d*))");
                Matcher m4 = p4.matcher(line);
                if(m4.find()) {
                    System.out.println(line);
                    System.out.println("优惠=" + m4.group(4));
                    System.out.println(count);
                    ws.addCell(new Label(0, count, name));
                    ws.addCell(new Label(1, count, time));
                    ws.addCell(new Label(4, count, m4.group(4)));
                    count ++;
                    continue;
                }

                Pattern p5 = Pattern.compile("\\s*(税收优惠)(\\s*)(--\\s)?((-*)(\\d*,)*(\\d*\\.\\d*))");
                Matcher m5 = p5.matcher(line);
                if(m5.find()) {
                    System.out.println(line);
                    System.out.println("税收优惠=" + m5.group(4));
                    System.out.println(count);
                    ws.addCell(new Label(0, count, name));
                    ws.addCell(new Label(1, count, time));
                    ws.addCell(new Label(5, count, m5.group(4)));
                    count ++;
                    continue;
                }

                Pattern p6 = Pattern.compile("\\s*(递延所得税费用|递延所得税资产)(\\s*)(--\\s)?((-*)(\\d*,)*(\\d*\\.\\d*))");
                Matcher m6 = p6.matcher(line);
                if(m6.find()) {
                    System.out.println(line);
                    System.out.println("递延所得税费用=" + m6.group(4));
                    System.out.println(count);
                    ws.addCell(new Label(0, count, name));
                    ws.addCell(new Label(1, count, time));
                    ws.addCell(new Label(6, count, m6.group(4)));
                    count ++;
                    continue;
                }
            }

            if(br != null) {
                br.close();
                br = null;
            }
        } catch (IOException e) {
           e.printStackTrace();
        } catch (RowsExceededException e) {
            e.printStackTrace();
        } catch (WriteException e) {
            e.printStackTrace();
        }
    }

最后加上main方法,批量处理目录下的pdf文件

public static void main(String[] args) {
        //将当前目录下的pdf文件转成txt文件
        File f = new File(System.getProperty("user.dir")); //获得当前路径
        File[] files = f.listFiles();
        for(File pdf : files) {
            //对pdf文件进行操作
            if(pdf.getName().matches(".*\\.pdf$")) {
                PDFtoTXT(pdf);
            }
        }

        files = f.listFiles(); //重新获得当前目录下的文件
        initExcel();
        for(File txt : files) {
            //对txt文件进行操作
            if(txt.getName().matches(".*\\.txt$")) {
                TXTtoEXCEL(txt);
            }
        }

        try {
            //从内存中写入文件中
            wwb.write();
            //关闭资源,释放内存
            wwb.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (WriteException e) {
            e.printStackTrace();
        }


//      删除产生的txt文件
        for(File file : files) {
            if(file.getName().matches(".*\\.pdf$")) {
                new File(file.getName().split("\\.")[0] + ".txt").delete();
            }
        }

    }

猜你喜欢

转载自blog.csdn.net/baidu_34045013/article/details/52727429
今日推荐