JAVA生成WORD文件的方案


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。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章