Web平臺下JAVA生成WORD文件的方法目前有以下三種:
一、 是jacob。 但是侷限於windows平臺,往往許多JAVA程序運行於其他操作系統,在此不討論該方案。
二、 是POI。 但是它的excel處理還湊合, word模塊還侷限於讀取word的文本內容,寫word文件的功能就更弱;還有一個要命的地方,處理doc格式和處理docx格式的類幾乎完全不同,要分開針對不同的格式寫不同的代碼,這就意味着用戶上傳的docx格式文件如果使用了doc的擴展名,程序馬上異常終止,但是如果項目的預算有限,也是隻能考慮POI了。
OI對word文件操作的代碼:
package org.apache.poi.xwpf.usermodel;
import java.io.FileOutputStream;
public class SimpleDocument {
public static void main(String[] args)throws Exception {
XWPFDocument doc = new XWPFDocument();
XWPFParagraph p1 = doc.createParagraph();
p1.setAlignment(ParagraphAlignment.CENTER);
p1.setBorderBottom(Borders.DOUBLE);
p1.setBorderTop(Borders.DOUBLE);
p1.setBorderRight(Borders.DOUBLE);
p1.setBorderLeft(Borders.DOUBLE);
p1.setBorderBetween(Borders.SINGLE);
p1.setVerticalAlignment(TextAlignment.TOP);
XWPFRun r1 = p1.createRun();
r1.setBold(true);
r1.setText("The quick brownfox");
r1.setBold(true);
r1.setFontFamily("Courier");
r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
r1.setTextPosition(100);
XWPFParagraph p2 = doc.createParagraph();
p2.setAlignment(ParagraphAlignment.RIGHT);
//BORDERS
p2.setBorderBottom(Borders.DOUBLE);
p2.setBorderTop(Borders.DOUBLE);
p2.setBorderRight(Borders.DOUBLE);
p2.setBorderLeft(Borders.DOUBLE);
p2.setBorderBetween(Borders.SINGLE);
XWPFRun r2 = p2.createRun();
r2.setText("jumped over the lazydog");
r2.setStrike(true);
r2.setFontSize(20);
XWPFRun r3 = p2.createRun();
r3.setText("and went away");
r3.setStrike(true);
r3.setFontSize(20);
r3.setSubscript(VerticalAlign.SUPERSCRIPT);
XWPFParagraph p3 = doc.createParagraph();
p3.setWordWrap(true);
p3.setPageBreak(true);
//p3.setAlignment(ParagraphAlignment.DISTRIBUTE);
p3.setAlignment(ParagraphAlignment.BOTH);
p3.setSpacingLineRule(LineSpacingRule.EXACT);
p3.setIndentationFirstLine(600);
XWPFRun r4 = p3.createRun();
r4.setTextPosition(20);
r4.setText("To be, or not to be:that is the question: "
+"Whether 'tis nobler in the mind to suffer "
+ "The slings and arrows ofoutrageous fortune, "
+"Or to take arms against a sea of troubles, "
+"And by opposing end them? To die: to sleep; ");
r4.addBreak(BreakType.PAGE);
r4.setText("No more; and by asleep to say we end "
+ "The heart-ache and the thousandnatural shocks "
+"That flesh is heir to, 'tis a consummation "
+"Devoutly to be wish'd. To die, to sleep; "
+ "To sleep: perchance to dream:ay, there's the rub; "
+ ".......");
r4.setItalic(true);
//This would imply that this break shall betreated as a simple line break, and break the line after that word:
XWPFRun r5 = p3.createRun();
r5.setTextPosition(-10);
r5.setText("For in that sleep ofdeath what dreams may come");
r5.addCarriageReturn();
r5.setText("When we have shuffled offthis mortal coil,"
+"Must give us pause: there's the respect"
+ "That makes calamity of so longlife;");
r5.addBreak();
r5.setText("For who would bear thewhips and scorns of time,"
+ "The oppressor's wrong, theproud man's contumely,");
r5.addBreak(BreakClear.ALL);
r5.setText("The pangs of despisedlove, the law's delay,"
+ "The insolence of office and thespurns" + ".......");
FileOutputStream out = newFileOutputStream("simple.docx");
doc.write(out);
out.close();
}
}
三、 是使用PageOffice 組件生成。這種效果(個人認爲)是目前最好的方法,提供的接口和對象都簡潔高效,開發效率很高。不僅支持從一個空白的document生成文件,還可以使用現有的word模板做數據填充,還可以把多個word模板插入到一個word模板中不同的位置來組合生成文件,例如做一個試卷生成系統,甚至還可以插入圖片和Excel文件到word模板中的指定位置去生成一個複合型的文檔報表,功能異常強大。但用這個產品也有一個缺點,就是這個是一個收費的產品,需要購買,但是隻要項目預算充足,這是一個值得選擇的方案。下面列舉幾個生成文件的效果代碼:
1) 從空白生成文件的代碼:
WordDocumentdoc = new WordDocument();
//設置內容標題
//創建DataRegion對象,PO_title爲自動添加的書籤名稱,書籤名稱需以“PO_”爲前綴,切書籤名稱不能重複
//三個參數分別爲要新插入書籤的名稱、新書籤的插入位置、相關聯的書籤名稱(“[home]”代表Word文檔的第一個位置)
DataRegion title =doc.createDataRegion("PO_title", DataRegionInsertType.After,"[home]");
//給DataRegion對象賦值
title.setValue("JAVA中編程實例\n");
//設置字體:粗細、大小、字體名稱、是否是斜體
title.getFont().setBold(true);
title.getFont().setSize(20);
title.getFont().setName("黑體");
title.getFont().setItalic(false);
//定義段落對象
ParagraphFormat titlePara =title.getParagraphFormat();
//設置段落對齊方式
titlePara.setAlignment(WdParagraphAlignment.wdAlignParagraphCenter);
//設置段落行間距
titlePara.setLineSpacingRule(WdLineSpacing.wdLineSpaceMultiple);
//設置內容
//第一段
//創建DataRegion對象,PO_body爲自動添加的書籤名稱
DataRegion body =doc.createDataRegion("PO_body", DataRegionInsertType.After,"PO_title");
//設置字體:粗細、是否是斜體、大小、字體名稱、字體顏色
body.getFont().setBold(true);
body.getFont().setItalic(true);
body.getFont().setSize(10);
//設置中文字體名稱
body.getFont().setName("楷體");
//設置英文字體名稱
body.getFont().setNameAscii("Times NewRoman");
body.getFont().setColor(Color.red);
//給DataRegion對象賦值
body.setValue("首先,我向大家介紹一下套接字的概念。\n");
//創建ParagraphFormat對象
ParagraphFormat bodyPara =body.getParagraphFormat();
//設置段落的行間距、對齊方式、首行縮進
bodyPara.setLineSpacingRule(WdLineSpacing.wdLineSpaceAtLeast);
bodyPara.setAlignment(WdParagraphAlignment.wdAlignParagraphLeft);
bodyPara.setFirstLineIndent(21);
2) 在一個word模板的文件中插入一個圖片、word和Excel文檔的代碼:
WordDocumentdoc = new WordDocument();
//插入圖片
DataRegion body4 =doc.createDataRegion("PO_body4", DataRegionInsertType.After,"PO_body3");// PO_body3是word模板中已存在的一個書籤
body4.setValue("[p_w_picpath]doc/logo.png[/p_w_picpath]");
//body4.Value ="[word]doc/1.doc[/word]";//嵌入其他Word文件
//body4.Value= "[excel]doc/1.xls[/excel]";//嵌入其他Excel文件
ParagraphFormat bodyPara4 = body4.getParagraphFormat();
bodyPara4.setAlignment(WdParagraphAlignment.wdAlignParagraphCenter);
3) 操作word中的表格代碼:
WordDocumentdoc = new WordDocument();
//打開數據區域
DataRegion dataRegion =doc.openDataRegion("PO_regTable");
//打開table,openTable(index)方法中的index代表Word文檔中table位置的索引,從1開始
Table table = dataRegion.openTable(1);
//給table中的單元格賦值, openCellRC(int,int)中的參數分別代表第幾行、第幾列,從1開始
table.openCellRC(3, 1).setValue("A公司");
table.openCellRC(3, 2).setValue("開發部");
table.openCellRC(3, 3).setValue("李清");
//插入一行,insertRowAfter方法中的參數代表第幾行,從1開始
table.insertRowAfter(3);
table.openCellRC(4, 1).setValue("B公司");
table.openCellRC(4, 2).setValue("銷售部");
table.openCellRC(4, 3).setValue("張三");
4) 給word添加一個水印,對於實現這個效果來說,PageOffice確實已經做到簡單到極致,如果用POI那個方案,抱歉本人沒有找到相關的資料,但 PageOffice的代碼只用下面一句:
WordDocument doc =new WordDocument();
//添加水印,設置水印的內容
doc.getWaterMark().setText("北京某某公司");
很簡單吧。。。
採用這個方案的缺點上面已經說過了,優點有以下幾點:不限制於Windows平臺;接口和對象的設計就是針對Office文件生成專門優化設計的,調用代碼簡單,寫起來比較舒服可讀性強;編程的工作量更小,如果開發中也利用了Word模板,那開發量可以更低;生成的文件是地地道道的Word格式,生成的文件效果比較完美;也不需要像POI那樣必須對doc和docx格式分別寫代碼;最後一點:服務器端不需要安裝Office,不使用服務器端資源,所以不需要處理服務器端文件生成時的併發問題,也就是很多用戶同時訪問系統生成文件時服務器的壓力問題。請注意這點,採用這個方案的話,文件是在客戶端生成的,調用的是客戶端的資源,完全符合分佈式計算的思想。服務器端壓力越小,系統就更穩定,這也是爲什麼個人認爲這是一種推薦方案。另外PageOffice除了能導入導出Word、Excel外,還能在線顯示、編輯、打印生成的文檔,而POI只能生成文檔,沒有在線功能。測試發現PageOffice的在線功能也是目前市場上做的最好最穩定可靠的一款。個人認爲,如果預算不是很緊張的話,應當毫不猶豫上PageOffice。