Java中各种文件类型的操作.doc_第1页
Java中各种文件类型的操作.doc_第2页
Java中各种文件类型的操作.doc_第3页
Java中各种文件类型的操作.doc_第4页
Java中各种文件类型的操作.doc_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

7.1 使用PDFBox处理PDF文档PDF全称Portable Document Format,是Adobe公司开发的电子文件格式。这种文件格式与操作系统平台无关,可以在Windows、Unix或Mac OS等操作系统上通用。PDF文件格式将文字、字型、格式、颜色及独立于设备和分辨率的图形图像等封装在一个文件中。如果要抽取其中的文本信息,需要根据它的文件格式来进行解析。幸好目前已经有不少工具能帮助我们做这些事情。7.1.1 PDFBox的下载最常见的一种PDF文本抽取工具就是PDFBox了,访问网址/projects/pdfbox/,进入如图7-1所示的下载界面。图7-1 PDFBox的下载页面读者可以在该网页下载其最新的版本。本书采用的是PDFBox-0.7.3版本。PDFBox是一个开源的Java PDF库,这个库允许你访问PDF文件的各项信息。在接下来的例子中,将演示如何使用PDFBox提供的API,从一个PDF文件中提取出文本信息。7.1.2 在Eclipse中配置以下是在Eclipse中创建工程,并建立解析PDF文件的工具类的过程。(1)在Eclipse的workspace中创建一个普通的Java工程:ch7。(2)把下载的PDFBox-0.7.3.zip解压,解压后的目录结构如图7-2所示。图7-2 解压后的PDFBox包(3)进入external目录下,可以看到,这里包括了PDFBox所有用到的外部包。复制下面的Jar包到工程ch7的lib目录下(如还未建立lib目录,则先创建一个)。l bcmail-jdk14-132.jarl bcprov-jdk14-132.jarl checkstyle-all-4.2.jarl FontBox-0.1.0-dev.jarl lucene-core-2.0.0.jar然后再从PDFBox的lib目录下,复制PDFBox-0.7.3.jar到工程的lib目录下。(4)在工程上单击右键,在弹出的快捷菜单中选择“Build Path-Config Build Path-Add Jars”命令,把工程lib目录下面的包都加入工程的Build Path。笔者机器上完整的工程目录如图7-3所示:图7-3 工程截图7.1.3 使用PDFBox解析PDF内容在刚刚创建的Eclipse工程中,创建一个ch7.pdfbox包,并创建一个PdfboxTest类。该类包含一个getText方法,用于从一个PDF中获取文本信息,其代码如下。代码7.1public void geText(String file) throws Exception / 是否排序 boolean sort = false;/ pdf文件名 String pdfFile = file;/ 输入文本文件名称 String textFile = null;/ 编码方式 String encoding = UTF-8;/ 开始提取页数 int startPage = 1;/ 结束提取页数 int endPage = Integer.MAX_VALUE;/ 文件输入流,生成文本文件 Writer output = null;/ 内存中存储的PDF Document PDDocument document = null;try try / 首先当作一个URL来装载文件,如果得到异常再从本地文件系统/去装载文件 URL url = new URL(pdfFile); document = PDDocument.load(url); / 获取PDF的文件名 String fileName = url.getFile(); / 以原来PDF的名称来命名新产生的txt文件 if (fileName.length() 4) File outputFile = new File(fileName.substring(0, fileName.length() - 4) + .txt); textFile = outputFile.getName(); catch (MalformedURLException e) / 如果作为URL装载得到异常则从文件系统装载 document = PDDocument.load(pdfFile); if (pdfFile.length() 4) textFile = pdfFile.substring(0, pdfFile.length() - 4) + .txt; / 文件输入流,写入文件倒textFile output = new OutputStreamWriter(new FileOutputStream(textFile), encoding); / PDFTextStripper来提取文本 PDFTextStripper stripper = null; stripper = new PDFTextStripper();/ 设置是否排序 stripper.setSortByPosition(sort);/ 设置起始页 stripper.setStartPage(startPage);/ 设置结束页 stripper.setEndPage(endPage);/ 调用PDFTextStripper的writeText提取并输出文本 stripper.writeText(document, output); finally if (output != null) / 关闭输出流 output.close(); if (document != null) / 关闭PDF Document document.close(); 在上面的代码中,getText方法接收一个String类型的参数,指定要提取的PDF文件路径。这个位置可以是一个URL或本地文件。然后函数调用PDFBox提供的PDFTextStripper类,设置提取过程中的一些属性(如起始页、是否排序等)。最后将文本提取并写入文件。7.1.4 运行效果下面看一下这个函数的运行效果,在PdfboxTest加入一个main函数,其代码如下。public static void main(String args) PdfboxTest test = new PdfboxTest(); try / 取得C盘下的index.pdf的内容 test.geText(C:index.pdf); catch (Exception e) e.printStackTrace(); 这里要处理一个index.pdf文件,该PDF文件的内容如图7-4所示。图7-4 要解析的PDF文档内容通过PdfboxTest处理后的文本文件如图7-5所示。图7-5 处理的结果可以看到,PDF中的文本已经被提取出来,保存于文本文件中了。其中第4行的超链接部分“POI News WebBlog”,在文本文件中已经被替换成了普通的纯文本。读者可以根据PDFBox所提供的API文档进一步查询其他功能。7.1.5 与Lucene的集成PDFBox还提供和Lucene的集成,它提供了一套简单的方法把PDF Documents加入到Lucene的索引中去,请看以下代码:Document lucenedocument = LucenePDFDocument.getDocument();其中,LucenePDFDocument是PDFBox中提供的一个类,它的getDocument被重载为3个方法,分别接收一个File对象、InputStream对象或者URL对象作为参数,然后从该参数传递进来的PDF文件中,提取并生成Lucene的Document对象。当通过PDFBox从一个PDF文档中得到一个Lucene Document后,可以直接使用IndexWriter把它加到Lucene的index中。LucenePDFDocument自动从PDF文件中提取各种元数据Field,并把它们加入到Document中。它提取的信息如表7-1所示。表7-1 PDFBox生成的Lucene Document格式Lucene Field名称说明path文件系统路径(如果文档是从文件装载)urlURL地址(如果文档是从网络装载)contents整个Document的内容,索引但不存储summaryDocument的内容前500个字符modified最后修改时间uidDocument的惟一IDCreationDate从PDF的meta-data获取Creator从PDF的meta-data获取Keywords从PDF的meta-data获取ModificationDate从PDF的meta-data获取Producer从PDF的meta-data获取Subject从PDF的meta-data获取Trapped从PDF的meta-data获取下面通过LucenePDFDocument,直接对PDF建立索引,在ch7.pdfbox包下面新建一个PdfLuceneTest类,该类的代码如下。代码7.2public class PdfLuceneTest public static void main(String args) try / IndexWriter存放索引到d:index下 IndexWriter writer = new IndexWriter(d:index, new StandardAnalyzer(), true); / LucenePDFDocument返回由PDF产生的Lucene Docuement Document d = LucenePDFDocument .getDocument(new File(C:index.pdf); / 写入索引 writer.addDocument(d); / 关闭索引文件流 writer.close(); / 读取d:index下的索引文件建立IndexSearcher IndexSearcher searcher = new IndexSearcher(d:index); / 对索引的contents Field进行查找关键词poi Term t = new Term(contents, poi); / 根据Term生成Query Query q = new TermQuery(t); / 搜索返回结果集 Hits hits = searcher.search(q); / 打印结果集 for (int i = 0; i sheet.getLastRowNum() / 当前行位置清零 currPosition = 0; / 判断是否还有Sheet while (currSheet != numOfSheets - 1) / 得到下一张Sheet sheet = workbook.getSheetAt(currSheet + 1); / 当前行数是否已经到达文件末尾 if (currPosition = sheet.getLastRowNum() / 当前Sheet指向下一张Sheet currSheet+; continue; else / 获取当前行数 int row = currPosition; currPosition+; / 读取当前行数据 return getLine(sheet, row); return null; / 获取当前行数 int row = currPosition; currPosition+; / 读取当前行数据 return getLine(sheet, row); return null; / 函数getLine返回Sheet的一行数据 private String getLine(HSSFSheet sheet, int row) / 根据行数取得Sheet的一行 HSSFRow rowline = sheet.getRow(row); / 创建字符创缓冲区 StringBuffer buffer = new StringBuffer(); / 获取当前行的列数 int filledColumns = rowline.getLastCellNum(); HSSFCell cell = null; / 循环遍历所有列 for (int i = 0; i filledColumns; i+) / 取得当前Cell cell = rowline.getCell(short) i); String cellvalue = null; if (cell != null) / 判断当前Cell的Type switch (cell.getCellType() / 如果当前Cell的Type为NUMERIC case HSSFCell.CELL_TYPE_NUMERIC: / 判断当前的cell是否为Date if (HSSFDateUtil.isCellDateFormatted(cell) / 如果是Date类型则,取得该Cell的Date值 Date date = cell.getDateCellValue(); / 把Date转换成本地格式的字符串 cellvalue = cell.getDateCellValue().toLocaleString(); / 如果是纯数字 else / 取得当前Cell的数值 Integer num = new Integer(int) cell .getNumericCellValue(); cellvalue = String.valueOf(num); break; / 如果当前Cell的Type为STRIN case HSSFCell.CELL_TYPE_STRING: / 取得当前的Cell字符串 cellvalue = cell.getStringCellValue().replaceAll(, ); break; / 默认的Cell值 default: cellvalue = ; else cellvalue = ; / 在每个字段之间插入分割符 buffer.append(cellvalue).append(EXCEL_LINE_DELIMITER); / 以字符串返回该行的数据 return buffer.toString(); / close函数执行流的关闭操作 public void close() / 如果is不为空,则关闭InputSteam文件输入流 if (is != null) try is.close(); catch (IOException e) is = null; / 如果reader不为空则关闭BufferedReader文件输入流 if (reader != null) try reader.close(); catch (IOException e) reader = null; 7.3.2 ExcelReader的运行效果下面创建一个main函数,用来测试上面的ExcelReader类,代码如下。代码7.7 public static void main(String args) try ExcelReader er=new ExcelReader(c:xp.xls); String line=er.readLine(); while(line != null) System.out.println(line); line=er.readLine(); er.close(); catch(Exception e) e.printStackTrace(); main函数先创建一个ExcelReader类,然后调用它提供的接口readLine,对XLS文件进行读取,打印到控制台,处理前的XLS文件如图7-12所示。图7-12 处理前的XLS文件内容运行main函数进行内容提取后,Eclipse的控制台输出如图7-13所示。图7-13 输出结果可以看到,Excel文件中的内容已经被成功的输出了出来。7.3.3 POI中Excel文件Cell的类型在读取每一个Cell的值的时候,通过getCellType方法获得当前Cell的类型,在Excel中Cell有6种类型,如表7-3所示。表7-3 Cell的类型CellType说明CELL_TYPE_BLANK空值CELL_TYPE_BOOLEAN布尔型CELL_TYPE_ERROR错误CELL_TYPE_FORMULA公式型CELL_TYPE_STRING字符串型CELL_TYPE_NUMERIC数值型本例采用了CELL_TYPE_STRING和CELL_TYPE_NUMERIC类型,因为在Excel文件中只有字符串和数字。如果Cell的Type为CELL_TYPE_NUMERIC时,还需要进一步判断该Cell的数据格式,因为它有可能是Date类型,在Excel中的Date类型也是以Double类型的数字存储的。Excel中的Date表示当前时间与1900年1月1日相隔的天数,所以需要调用HSSFDateUtil的isCellDateFormatted方法,判断该Cell的数据格式是否是Excel Date类型。如果是,则调用getDateCellValue方法,返回一个Java类型的Date。实际上Excel的数据格式有很多,还支持用户自定义的类型,在Excel中,选择一个单元格然后右键选择“设置单元格格式”,在弹出的单元格格式中选中“数字”,如图7-14所示。图7-14 Excel的单元格格式图中的数据有数值、货币、时间、日期、文本等格式。这些数据格式在POI中的HSSFDataFormat类里都有相应的定义。HSSFDataFormat是HSSF子项目里面定义的一个类。类HSSFDataFormat允许用户新建数据格式类型。HSSFDataFormat类包含静态方法staticjava.lang.String getBuiltinFormat(shortindex),它可以根据编号返回内置数据类型。另外staticshort getBuiltinFormat(java.lang.Stringformat)方法则可以根据数据类型返回其编号,staticjava.util.List getBuiltinFormats()可以返回整个内置的数据格式列表。在HSSFDataFormat里一共定义了49种内置的数据格式,如表7-4所示。表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论