PDF文档解析java Big Faceless
最近在公司实习,由于公司的项目,公司要求我们做解析文档的部分任务,首先我做的是PDF文档的解析,主管也说了,这是最简单的,用开源的JAVA库PDFbox就能解决,不过,pdfbox还不支持新的PDF1.7版本。我在网上搜索,终于找到了能支持PDF1.7版本的开源库了。The Big Faceless PDF Library可以到一下网站下载PDF包:里面有较详细的文档说明。 http://big.faceless.org/products/pdf/
发现比PDFbox还简单。
下面是我的代码:
import java.io.*;
import org.faceless.pdf2.*;
public class PrintPDF {
public static void main(String[] args) throws IOException {
//PDF文档路径
String filepath = "d://userguide.pdf";
//PDFReader对象建立
PDFReader reader = new PDFReader(new File(filepath));
//建立PDF文档对象
PDF pdf = new PDF(reader);
//建立文档解析对象
PDFParser parser = new PDFParser(pdf);
for (int i = 0; i < pdf.getNumberOfPages(); i++) {
PageExtractor extractor = parser.getPageExtractor(i);
System.out.println(extractor.getTextAsStringBuffer());
}
}
}
纯文本格式的pdf我已经解析出来了,但是我还要解析图片版本或者文字版中带图片的pdf。
解析纯文本的代码如下:
package pdfbox;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.*;
public class pdf2 {
public static String getText(String file){
String s="";
String pdffile=file;
PDDocument pdfdoc=null;
try {
pdfdoc=PDDocument.load(pdffile);
PDFTextStripper stripper=new PDFTextStripper();
s=stripper.getText(pdfdoc);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
if (pdfdoc!=null){
pdfdoc.close();
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return s;
}
public static void toTextFile(String doc,String filename) throws Exception{
String pdffile=doc;
PDDocument pdfdoc=PDDocument.load(doc);
try {
pdfdoc=PDDocument.load(pdffile);
PDFTextStripper stripper=new PDFTextStripper();
PrintWriter pw=new PrintWriter(new FileWriter(filename));
stripper.writeText(pdfdoc, pw);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
if (pdfdoc!=null){
pdfdoc.close();
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String sc=getText("E:/solution.pdf");
System.out.print(sc);
toTextFile("E:/solution.pdf","E:/solution.txt");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
解析图片: PDDocumentCatalog cata = document.getDocumentCatalog();
List pages = cata.getAllPages();
int count = 1;
for( int i = 0; i < pages.size(); i++ )
{
PDPage page = ( PDPage ) pages.get( i );
if( null != page )
{
PDResources res = page.findResources();
//获取页面图片信息
Map imgs = res.getImages();
if( null != imgs )
{
Set keySet = imgs.keySet();
Iterator it = keySet.iterator();
while( it.hasNext() )
{
Object obj = it.next();
PDXObjectImage img = ( PDXObjectImage ) imgs.get( obj );
img.write2file( imgSavePath + count );
count++;
}
}
}
}
itext不论是旧的版本,还是新的版本,其核心包都不支持中文问题。这样就会造成在生成含有中文的pdf文档时,
中文不能正常显示的问题。要使itext支持中文,需要下载iTextAsian.jar包
编写支持中文的字体对象:
PdfWriter.getInstance(document, new FileOutputStream("123.pdf"));
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
Font fontChinese = new Font(bfChinese);
document.open();
Paragraph par = new Paragraph("你好",fontChinese);
document.add(par);
这样就解决了itext对这中文的支持。
注意:如果运行报错。(找不到资源包)。明明导入了iTextAsian.jar包怎么会找不到资源包呢。
这时我们查看一下iTextAsian.jar包发现包名:com.lowagie.text.pdf.fonts
而查看itext的Font的包名:com.itextpdf.text.pdf.fonts
原来iTextAsian.jar对iText的扩展,是通过在相同的包空间下加入字体来解决的,然而,新的iText的包空间命名
与久的版本有很大的差别。
解决办法时,解压iTextAsian.jar包,修改iTextAsian.jar包名于itext的包名命名规则一直,再从新生成jar包。
因为iTextAsian.jar为资源包,不为java文件,所以修改包名对iTextAsian.jar无影响
用java怎么提取或是解压rar压缩文档?以前查了很多的资料,没有找到相关的第三方库,网上查找的资料说是解析rar只能更加rar的命令行参数来解析。因为rar压缩文档的内部结构是没有共开的。所以没有专门的解析库程序。自己也就只好用命令行了,但是在实际应用中,遇到rar加密时就遇到了问题。
所以自己又在网上很费心的找了相关资料,终于找到了一个库可以解析rar文档。
库下载地址: http://www.mucommander.com/。这是个解决多种文档的软件,是用java写的。所以能够引用来解决rar的解析。package DOCExtract;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import DocHandler.DocTypeNameParse;
import DocHandler.IDocHandler;
import com.mucommander.file.AbstractFile;
import com.mucommander.file.FileFactory;
import com.mucommander.file.impl.rar.provider.RarFile;
import com.mucommander.file.impl.rar.provider.de.innosystec.unrar.rarfile.FileHeader;
/**
* IDocHandler 为自己写的接口类
*
*/
public class RarExtractor implements IDocHandler {
// 每次读取的字节大小
private int BLOCKSIZE = 1024;
// 临时文件编号
private int FILE_COUNT = 0;
public int getText(InputStream inputStream, StringBuffer strBuff) {
String fileDir = "f://wang" + FILE_COUNT;
FILE_COUNT++;
String fileName = null;
try { // 将文件写入磁盘上
writeTodev(inputStream, fileDir);
// 从磁盘上读取文件
File file = new File(fileDir);
String[] subFilePath = file.list();
fileName = fileDir + "//" + subFilePath[0];
AbstractFile abstractFile = FileFactory.getFile(fileName);
RarFile rarFile = new RarFile(abstractFile);
Collection collection = rarFile.getEntries();
IDocHandler docHandler = null;
for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
FileHeader fileHeader = (FileHeader) iterator.next();
String subFileName = fileHeader.getFileNameString();
// 输出rar文档里的文档名
System.out.println("subFileName:" + subFileName);
InputStream subinputStream = rarFile.getEntryInputStream(subFileName);
/**
* DocTypeNameParse为文自己写的文档类型判断类。
*/
String fileType = DocTypeNameParse.getTypeName(subFileName);
// 输出文档的类型
System.out.println("fileType:" + fileType);
docHandler = (IDocHandler) this.ExctractMap.get(fileType);
docHandler.getText(subinputStream, strBuff);
subinputStream.close();//这里必须关闭流,否则在遇到有文档异常时,流就会卡主
}
// System.out.println("strBuff:" + strBuff);
} catch (IOException e) {
e.printStackTrace();
}
// 删除临时文件
deleteFile(fileDir);
return 0;
}
// 将文件写入磁盘上
private void writeTodev(InputStream inputStream, String fileDir) {
byte[] b = new byte[BLOCKSIZE];
int readCount = 0;
try {
File file = new File(fileDir);
if (!file.exists())
file.mkdirs();
File subFile = new File(fileDir, "tempfile.rar");
FileOutputStream os = new FileOutputStream(subFile);
while ((readCount = inputStream.read(b)) > 0) {
os.write(b, 0, readCount);
}
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 删除临时文件
private void deleteFile(String fileName) {
File file = new File(fileName);
File[] subFile = file.listFiles();
for (int i = 0; i < subFile.length; i++) {
subFile[i].delete();
}
file.delete();
}
}