java操作word/excel/pdf等檔案技術方案
最近專案中遇到很多對word/excel/pdf等檔案的操作,解決方案有好多,開源免費有:利用openoffice元件(需要安裝openoffice軟體),poi,itext等。也有收費的服務:aspose(特別好用,也有點貴)。
我專案中需求可以概括為匯出word(包括文字,表格,圖片),把pdf插入到word,word之間的合併。
這裡按需求介紹一下我走通的技術方案:
匯出word 可以使用poi,aspose。(其實poi操作word還是有些不方便的,用itext好一些,當然aspose都可以幹,只不過要花錢!!)
關於這方面的資料挺少的,api都挺好使用的,只不過一開始面對忙忙多的類,會有無從下手的感覺,特再此說明一些關鍵操作類。
無論採用哪種類庫,他們大致步奏是一樣的。一般都是新建一個段落,獲取畫筆。(由於本文主要提供技術方案及操作步奏,具體程式碼就不提供了,讀者可以根據作者思路及官方api進行操作)
poi操作word:poi操作word把doc/docx是分開的,建立word物件後,便可create paragraph(段落)了,在從paragraph.createRun(),獲取畫筆XWPFRun(我稱為畫筆),便可run設定文字字型,大小,通過setText()方法,變可以寫入文字。
生成表格,paragraph.createTable(),可以在create時聲稱table的大小,也可以動態新增行和列。
插入圖片:poi插入圖片有點問題,下面重寫了XWPFDocuemnt的插入圖片方法,讀者可以使用自己類代替自帶的XWPFDocument進行docx的操作
public class CustomXWPFDocument extends XWPFDocument {
public CustomXWPFDocument(InputStream in) throws IOException {
super(in);
}
/**
*
*/
public CustomXWPFDocument() {
super();
// TODO Auto-generated constructor stub
}
/**
* @param pkg
* @throws IOException
*/
public CustomXWPFDocument(OPCPackage pkg) throws IOException {
super(pkg);
// TODO Auto-generated constructor stub
} // picAttch 圖片後面追加的字串 可以是空格
public void createPicture(XWPFParagraph paragraph,int id, int width, int height,String picAttch) {
final int EMU = 9525;
width *= EMU;
height *= EMU;
String blipId = getAllPictures().get(id).getPackageRelationship()
.getId();
CTInline inline = paragraph.createRun().getCTR()
.addNewDrawing().addNewInline();
paragraph.createRun().setText(picAttch);
String picXml = ""
+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
+ " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
+ " <pic:nvPicPr>" + " <pic:cNvPr id=\""
+ id
+ "\" name=\"Generated\"/>"
+ " <pic:cNvPicPr/>"
+ " </pic:nvPicPr>"
+ " <pic:blipFill>"
+ " <a:blip r:embed=\""
+ blipId
+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
+ " <a:stretch>"
+ " <a:fillRect/>"
+ " </a:stretch>"
+ " </pic:blipFill>"
+ " <pic:spPr>"
+ " <a:xfrm>"
+ " <a:off x=\"0\" y=\"0\"/>"
+ " <a:ext cx=\""
+ width
+ "\" cy=\""
+ height
+ "\"/>"
+ " </a:xfrm>"
+ " <a:prstGeom prst=\"rect\">"
+ " <a:avLst/>"
+ " </a:prstGeom>"
+ " </pic:spPr>"
+ " </pic:pic>"
+ " </a:graphicData>" + "</a:graphic>";
// CTGraphicalObjectData graphicData =
inline.addNewGraphic().addNewGraphicData();
XmlToken xmlToken = null;
try {
xmlToken = XmlToken.Factory.parse(picXml);
} catch (XmlException xe) {
xe.printStackTrace();
}
inline.set(xmlToken);
// graphicData.set(xmlToken);
inline.setDistT(0);
inline.setDistB(0);
inline.setDistL(0);
inline.setDistR(0);
CTPositiveSize2D extent = inline.addNewExtent();
extent.setCx(width);
extent.setCy(height);
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
docPr.setId(id);
docPr.setName("圖片" + id);
docPr.setDescr("");
}
}
使用createPicture方法便可以插入圖片了。
儲存word:XWPFDocument有write方法,我們可以提供了FileOutputStream,便可直接儲存了。
aspose操作word:aspose真心好用,畢竟收費還這麼貴,首先通過Document例項化一個word物件(doc/docx)都可以,然後獲取DocumentBuilder(我稱之為畫筆),接下來所有的操作,包括畫表格都有它來完成,跟poi的使用還有點不一樣的,寫入文字,表格,圖片都是基於builder完成的,write是寫入文字的做法。
這裡跟poi有一個很大的不同,假設我們需要有個文字加黑操作,poi在加黑和不加黑就需要兩個run來處理,而aspose只需要用同一個builder來處理就好,builder.setBlod(),完全不影響該builder畫出的全部資料。
下面在來講講pdf插入word,合併word的操作。
很遺憾,poi/aspose.word是不支援直接插入pdf的,我這裡採用了pdfbox庫先將pdf轉為圖片,然後將圖片插入到word中。
word合併:aspose是直接支援合併word的,Document.append()方法直接合並。