1. 程式人生 > >java操作word/excel/pdf等檔案技術方案

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()方法直接合並。