用java生成word文档(转载)

时间:2021-12-21 05:40:10
用java生成word文档 poi是apache的一个项目,不过就算用poi你可能都觉得很烦,不过不要紧,这里提供了更加简单的一个接口给你:
下载经过封装后的poi包:
这个包就是:tm-extractors-0.4.jar
下载之后,放到你的classpath就可以了,下面是如何使用它的一个例子:
import java.io.*;
import org.textmining.text.extraction.WordExtractor;
/**
*

Title: pdf extraction


*

Description: email:chris@matrix.org.cn


*

Copyright: Matrix Copyright (c) 2003


*

Company: Matrix.org.cn


* @author chris
* @version 1.0,who use this example pls remain the declare
*/

public class PdfExtractor {
public PdfExtractor() {
}
public static void main(String args[]) throws Exception
{
FileInputStream in = new FileInputStream ("c://a.doc");
WordExtractor extractor = new WordExtractor();
String str = extractor.extractText(in);
System.out.println("the result length is"+str.length());
System.out.println("the result is"+str);
}
}

如果没有这个包呢?就是下面这段了

read word:

代码
  1. public class WordExtractor {   
  2.     public WordExtractor() {   
  3.     }   
  4.   
  5.     public String extractText(InputStream in) throws IOException {   
  6.         ArrayList text = new ArrayList();   
  7.         POIFSFileSystem fsys = new POIFSFileSystem(in);   
  8.   
  9.         DocumentEntry headerProps = (DocumentEntry) fsys.getRoot().getEntry("WordDocument");   
  10.         DocumentInputStream din = fsys.createDocumentInputStream("WordDocument");   
  11.         byte[] header = new byte[headerProps.getSize()];   
  12.   
  13.         din.read(header);   
  14.         din.close();   
  15.         // Prende le informazioni dall'header del documento   
  16.         int info = LittleEndian.getShort(header, 0xa);   
  17.   
  18.         boolean useTable1 = (info & 0x200) != 0;   
  19.   
  20.         //boolean useTable1 = true;   
  21.            
  22.         // Prende informazioni dalla piece table   
  23.         int complexOffset = LittleEndian.getInt(header, 0x1a2);   
  24.         //int complexOffset = LittleEndian.getInt(header);   
  25.            
  26.         String tableName = null;   
  27.         if (useTable1) {   
  28.             tableName = "1Table";   
  29.         } else {   
  30.             tableName = "0Table";   
  31.         }   
  32.   
  33.         DocumentEntry table = (DocumentEntry) fsys.getRoot().getEntry(tableName);   
  34.         byte[] tableStream = new byte[table.getSize()];   
  35.   
  36.         din = fsys.createDocumentInputStream(tableName);   
  37.   
  38.         din.read(tableStream);   
  39.         din.close();   
  40.   
  41.         din = null;   
  42.         fsys = null;   
  43.         table = null;   
  44.         headerProps = null;   
  45.   
  46.         int multiple = findText(tableStream, complexOffset, text);   
  47.   
  48.         StringBuffer sb = new StringBuffer();   
  49.         int size = text.size();   
  50.         tableStream = null;   
  51.   
  52.         for (int x = 0; x < size; x++) {   
  53.                
  54.             WordTextPiece nextPiece = (WordTextPiece) text.get(x);   
  55.             int start = nextPiece.getStart();   
  56.             int length = nextPiece.getLength();   
  57.   
  58.             boolean unicode = nextPiece.usesUnicode();   
  59.             String toStr = null;   
  60.             if (unicode) {   
  61.                 toStr = new String(header, start, length * multiple, "UTF-16LE");   
  62.             } else {   
  63.                 toStr = new String(header, start, length, "ISO-8859-1");   
  64.             }   
  65.             sb.append(toStr).append(" ");   
  66.   
  67.         }   
  68.         return sb.toString();   
  69.     }   
  70.   
  71.     private static int findText(byte[] tableStream, int complexOffset, ArrayList text)   
  72.         throws IOException {   
  73.         //actual text   
  74.         int pos = complexOffset;   
  75.         int multiple = 2;   
  76.         //skips through the prms before we reach the piece table. These contain data   
  77.         //for actual fast saved files   
  78.         while (tableStream[pos] == 1) {   
  79.             pos++;   
  80.             int skip = LittleEndian.getShort(tableStream, pos);   
  81.             pos += 2 + skip;   
  82.         }   
  83.         if (tableStream[pos] != 2) {   
  84.             throw new IOException("corrupted Word file");   
  85.         } else {   
  86.             //parse out the text pieces   
  87.             int pieceTableSize = LittleEndian.getInt(tableStream, ++pos);   
  88.             pos += 4;   
  89.             int pieces = (pieceTableSize - 4) / 12;   
  90.             for (int x = 0; x < pieces; x++) {   
  91.                 int filePos =   
  92.                     LittleEndian.getInt(tableStream, pos + ((pieces + 1) * 4) + (x *"/images/forum/smiles/icon_cool.gif"/> + 2);   
  93.                 boolean unicode = false;   
  94.                 if ((filePos & 0x40000000) == 0) {   
  95.                     unicode = true;   
  96.                 } else {   
  97.                     unicode = false;   
  98.                     multiple = 1;   
  99.                     filePos &= ~(0x40000000); //gives me FC in doc stream   
  100.                     filePos /= 2;   
  101.                 }   
  102.                 int totLength =   
  103.                     LittleEndian.getInt(tableStream, pos + (x + 1) * 4)   
  104.                         - LittleEndian.getInt(tableStream, pos + (x * 4));   
  105.   
  106.                 WordTextPiece piece = new WordTextPiece(filePos, totLength, unicode);   
  107.                 text.add(piece);   
  108.   
  109.             }   
  110.   
  111.         }   
  112.         return multiple;   
  113.     }   
  114.     public static void main(String[] args){   
  115.         WordExtractor w  = new WordExtractor();   
  116.         POIFSFileSystem ps = new POIFSFileSystem();   
  117.         try{   
  118.                
  119.             File file = new File("C://test.doc");   
  120.                
  121.             InputStream in = new FileInputStream(file);   
  122.             String s = w.extractText(in);   
  123.             System.out.println(s);   
  124.        
  125.                
  126.         }catch(Exception e){   
  127.             e.printStackTrace();   
  128.         }   
  129.                    
  130.     }   
  131.   
  132. }   
  133. class WordTextPiece {   
  134.     private int _fcStart;   
  135.     private boolean _usesUnicode;   
  136.     private int _length;   
  137.   
  138.     public WordTextPiece(int start, int length, boolean unicode) {   
  139.         _usesUnicode = unicode;   
  140.         _length = length;   
  141.         _fcStart = start;   
  142.     }   
  143.     public boolean usesUnicode() {   
  144.         return _usesUnicode;   
  145.     }   
  146.   
  147.     public int getStart() {   
  148.         return _fcStart;   
  149.     }   
  150.     public int getLength() {   
  151.         return _length;   
  152.     }   
  153.   
  154. }   
<script>render_code();</script>

 

write word

 

代码
  1. public boolean writeWordFile(String path, String content) {   
  2.     boolean w = false;   
  3.     try {   
  4.   
  5.     //  byte b[] = content.getBytes("ISO-8859-1");   
  6.         byte b[] = content.getBytes();   
  7.            
  8.         ByteArrayInputStream bais = new ByteArrayInputStream(b);   
  9.   
  10.         POIFSFileSystem fs = new POIFSFileSystem();   
  11.         DirectoryEntry directory = fs.getRoot();   
  12.   
  13.         DocumentEntry de = directory.createDocument("WordDocument", bais);   
  14.   
  15.         FileOutputStream ostream = new FileOutputStream(path);   
  16.   
  17.         fs.writeFilesystem(ostream);   
  18.            
  19.         bais.close();   
  20.         ostream.close();   
  21.   
  22.     } catch (IOException e) {   
  23.         e.printStackTrace();   
  24.     }   
  25.   
  26.     return w;   
  27. }   
<script>render_code();</script>
写操作的代码还是有些问题:打开WORD时提示要选择字符类型
希望能改进!

 这样写文件有问题,因为不是word格式。

当然这几个jar是少不了的
poi-2.5.1-final-20040804.jar
poi-contrib-2.5.1-final-20040804.jar
poi-scratchpad-2.5.1-final-20040804.jar

如果要直接用Jakarta POI HWPF,没提供编译好的下载,只是原码了,自己编译吧 jakarta POI开源项目组HWPF(在下载后的scratchpad目录里)是操作word文档,在这里作了个简单的例子
下载地址:http://www.apache.org/dist/jakarta/Poi/

<!--age contentType="text/html; charset=GBK" import="java.io.*,org.apache.poi.hwpf.HWPFDocument,org.apache.poi.hwpf.usermodel.*,org.apache.poi.hwpf.model.*"-->









<!--r /> HWPFDocument doc = new HWPFDocument(new FileInputStream("g://a.doc"));<br /> Range r = doc.getRange ();   //取得word文档的范围<br />   StyleSheet styleSheet = doc.getStyleSheet ();<br /> <br />   int sectionLevel = 0;<br />   int lenParagraph = r.numParagraphs ();//取得段落数<br />   int c=r.numCharacterRuns();<br />   int b=r.numSections();<br />   String s=r.text();<br />   boolean inCode = false;<br />   // Paragraph p;<br />   for (int x = 0; x < lenParagraph; x++)<br />   {<br />     Paragraph p = r.getParagraph (x);<br /> <br />     String text = p.text ();<br />    -->


    <!--ex-->

<!--r />     if (text.trim ().length () == 0)<br />     {<br />     continue;<br />     }<br /> <br /> <br />     }<br /> <br />   //doc.write(new FileOutputStream("g://b.doc"));<br /> <br /> <br /> <br /> -->
char:

section:

text:



 

 

 

 


java操作word,可以试试java2word 

 java2word 是一个在java程序中调用 MS Office Word 文档的组件(类库)。该组件提供了一组简单的接口,以便java程序调用他的服务操作Word 文档。
这些服务包括:
打开文档、新建文档、查找文字、替换文字,
插入文字、插入图片、插入表格,
在书签处插入文字、插入图片、插入表格等。
填充数据到表格中读取表格数据
1.1版增强的功能:
@指定文本样式,指定表格样式。如此,则可动态排版word文档。
@填充表格数据时,可指定从哪行哪列开始填充。配合输入数据的大小,你可以修改表中的任意部分,甚至只修改一个单元格的内容。
@合并单元格。
更多激动人心的功能见详细说明: http://www.heavenlake.com/java2word/doc
免费下载:http://dev.heavenlake.com:81/developer/listthreads?forum=8

用java生成word文档

作者 javasky @ 2006-06-10 14:22:04 这几日, 公司有个项目, 要用java生成word文档, 在网上找来找去也没有找到好的生成word文档的库, 找到apache的POI可以使用, 但是所有的release版中也没有支持word的class. 只能从svn上下载源代码编译.
后来发现java支持rtf格式的文档, word也支持, 于是乎便使用此产生word文档了. 呵呵..
java支持的rtf文档功能不是很强大, 我们可以借助于一些开源的库, 比如: itext就可以很好的支持. itext上有很多例子, 有兴趣的可以上去看一下, 这里就不摘录了.
但是itext比较大要1.4M, 不是很喜欢. 在sf上找来找去, 发现一个更小的库, 尽管功能不是很强大, 基本的功能都有, 他就是srw(Simple RTF Writer目前它的版本是0.6,好久都没有人维护了).
srw内置了很多例子,  例如: 我们要写一个简单的rtf, 我们只需要这么写:
public class TestSimpleRtf {
    
    private static final String FILE_NAME = "out_testsimplertf.rtf";
    
    public static void main(String[] args) {
        try {
            // RTF Dokument generieren (in Querformat)
            RTFDocument doc = new RTFDocument(PageSize.DIN_A4_QUER);
            // Anzeige-Zoom und Ansicht definieren
            doc.setViewscale(RTFDocument.VIEWSCALE_FULLPAGE);    // Anzeige-Zoom auf "komplette Seite" einstellen
            doc.setViewkind(RTFDocument.VIEWKIND_PAGELAYOUT);    // ViewMode auf Seitenlayout stellen
            
            Paragraph absatz = new Paragraph(18, 0, 16, Font.ARIAL, new TextPart("Simple RTF Writer Testdokument"));
            absatz.setAlignment(Paragraph.ALIGN_CENTER);
            doc.addParagraph(absatz);
            File savefile = new File(FILE_NAME);
            doc.save(savefile);
            System.out.println("Neues RTF Dokument erstellt: " + savefile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }            
    }
}
用法很简单, 但是功能很少, 比如没有table的功能, 不能设置打印方向等问题. 不过这个基本上就够用了.
后来, 我们的项目要求横向打印, 这可难坏了. 没办法, 自己查找word的rtf格式库, 拓展横向打印功能, 目前已经完成...
import com.itseasy.rtf.RTFDocument;
import com.itseasy.rtf.text.PageSize;

public class MyRTFDocument extends RTFDocument {
    public static final int ORIENTATION_PORTRAIT = 0;
    public static final int ORIENTATION_LANDSCAPE = 1;
    private int orientation;
    
    /**
     * 
     */
    public MyRTFDocument() {
        super();
    }
    /**
     * @param arg0
     */
    public MyRTFDocument(PageSize arg0) {
        super(arg0);
    }
    /* (non-Javadoc)
     * @see com.itseasy.rtf.RTFDocument#getDocumentAsString()
     */
    protected String getDocumentAsString() {
        StringBuffer sb = new StringBuffer(super.getDocumentAsString());
        int pos = -1;
        if (ORIENTATION_LANDSCAPE == orientation) {
            pos = sb.indexOf("paperw");
            if (pos > 0) {
                sb.insert(pos, "lndscpsxn");
            }
        }
        pos = 0;
        while((pos = sb.indexOf("pardplain", pos)) > 0){
            pos = sb.indexOf("{", pos);
            sb.insert(pos, "dbchaf2");
        }
        return sb.toString();
    }
    /**
     * @return Returns the orientation.
     */
    public int getOrientation() {
        return orientation;
    }
    /**
     * @param orientation The orientation to set.
     */
    public void setOrientation(int orientation) {
        this.orientation = orientation;
    }
    
}
在最近的一个项目中需要将一段字符类型的文本存为word,html并要将word的内容保存在数据库中,于是就有了如下的一个工具类,希望能对碰到这样需求的朋友提供点帮助。
       匆匆忙忙的就copy上来了,没有做一些删减,有一些多余的东西,有兴趣的朋友可以自行略去。我的注释相对比较清楚,可以按照自己的需求进行组合。
      在操作word的地方使用了jacob(jacob_1.9),这个工具网上很容易找到,将jacob.dll放置系统Path中,直接放在system32下也可以,jacob.jar放置在classPath中。


代码如下:WordBridge.java

/**
 * WordBridge.java
 */
package com.kela.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.kela.db.PoolingDataSource;

/**
 * 说明: 对word的操作


 *
 * @author   kela.kf@gmail.com
 */
public class WordBridge {
 
   Log log = LogFactory.getLog("WordBridgt");
 
   private ActiveXComponent MsWordApp = null; 
   private Dispatch document = null;
   
    /**
     * 打开word
     * @param makeVisible, true显示word, false不显示word
     */
    public void openWord(boolean makeVisible) {
       if (MsWordApp == null) {
         MsWordApp = new ActiveXComponent("Word.Application");
       }
  
       Dispatch.put(MsWordApp, "Visible", new Variant(makeVisible));
    }

    /**
     * 创建新的文档
     *
     */
    public void createNewDocument() {
       Dispatch documents = Dispatch.get(MsWordApp, "Documents").toDispatch();
       document = Dispatch.call(documents, "Add").toDispatch();
    }

    /**
     * 关闭文档
     */
    public void closeDocument() {
      // 0 = wdDoNotSaveChanges
      // -1 = wdSaveChanges
      // -2 = wdPromptToSaveChanges
      Dispatch.call(document, "Close", new Variant(0));
      document = null;
    }

    /**
     * 关闭word
     *
     */
    public void closeWord() {
       Dispatch.call(MsWordApp, "Quit");
       MsWordApp = null;
       document = null;
    }
 
    /**
     * 插入文本
     * @param textToInsert 文本内容
     */
    public void insertText(String textToInsert) {
       Dispatch selection = Dispatch.get(MsWordApp, "Selection").toDispatch();
       Dispatch.put(selection, "Text", textToInsert);
    }

    /**
     * 保存文件
     * @param filename
     */
    public void saveFileAs(String filename) {
      Dispatch.call(document, "SaveAs", filename);
    }

    /**
     * 将word转换成html
     * @param htmlFilePath
     */
    public void wordToHtml(String htmlFilePath) {
         Dispatch.invoke(document,"SaveAs", Dispatch.Method, new Object[]{htmlFilePath,new Variant(8)}, new int[1]);
     }

    /**
     * 保存word的同时,保存一个html
     * @param text 需要保存的内容
     * @param wordFilePath word的路径
     * @param htmlFilePath html的路径
     * @throws LTOAException
     */
    public void wordAsDbOrToHtml(String text, String wordFilePath, String htmlFilePath) throws LTOAException {
  
      try {
         openWord(false);
         createNewDocument();
         insertText(text);
         saveFileAs(wordFilePath);
         wordToHtml(htmlFilePath);
     } catch (Exception ex) {
         log.error("错误 - 对word的操作发生错误");
         log.error("原因 - " + ex.getMessage());
         throw new LTOAException(LTOAException.ERR_UNKNOWN, "对word的操作发生错误("
                    + this.getClass().getName() + ".wordAsDbOrToHtml())", ex);
     } finally {
         closeDocument();
         closeWord();
     }
  
   }

   /**
    * 将word保存至数据库
    * @param wordFilePath
    * @param RecordID
    * @throws LTOAException
    */
    public void wordAsDatabase(String wordFilePath, String RecordID) throws LTOAException {

       Connection conn = null;
       PreparedStatement pstmt = null;
       PoolingDataSource pool = null;
       
       File file = null;
    
       String sql = "";
       try {
           sql = " UPDATE Document_File SET FileBody = ? WHERE RecordID = ? ";
            
           pool = new PoolingDataSource();
           conn = pool.getConnection();
        
           file = new File(wordFilePath);
           InputStream is = new FileInputStream(file);
           byte[] blobByte = new byte[is.available()];
           is.read(blobByte);
           is.close();

          pstmt = conn.prepareStatement(sql);
          pstmt.setBinaryStream(1,(new ByteArrayInputStream(blobByte)), blobByte.length);
          pstmt.setString(2, RecordID); 
          pstmt.executeUpdate();
     
        } catch (Exception ex) {
            log.error("错误 - 表 Document_File 更新数据发生意外错误");
            log.error("原因 - " + ex.getMessage());
            throw new LTOAException(LTOAException.ERR_UNKNOWN,
                   "表Document_File插入数据发生意外错误("
                    + this.getClass().getName() + ".wordAsDatabase())", ex);
         } finally {
             pool.closePrepStmt(pstmt);
             pool.closeConnection(conn);
        }
    }
 
   /**
    * 得到一个唯一的编号
    * @return 编号
    */
   public String getRecordID() {
  
     String sRecordID = "";
  
     java.util.Date dt=new java.util.Date();
        long lg=dt.getTime();
        Long ld=new Long(lg);
        sRecordID =ld.toString();
       
        return sRecordID;
    }
 
    /**
     * 得到保存word和html需要的路径
     * @param systemType 模块类型 givInfo, sw, fw
     * @param fileType 文件类型 doc, html
     * @param recID 文件编号
     * @return 路径
     */
     public String getWordFilePath(String systemType, String fileType, String recID) {
  
       String filePath = "";