POI 关于对 ms word的读写代码
关键字: poi
read word:
- public class WordExtractor {
- public WordExtractor() {
- }
- public String extractText(InputStream in) throws IOException {
- ArrayList text = new ArrayList();
- POIFSFileSystem fsys = new POIFSFileSystem(in);
- DocumentEntry headerProps = (DocumentEntry) fsys.getRoot().getEntry("WordDocument");
- DocumentInputStream din = fsys.createDocumentInputStream("WordDocument");
- byte[] header = new byte[headerProps.getSize()];
- din.read(header);
- din.close();
- // Prende le informazioni dall'header del documento
- int info = LittleEndian.getShort(header, 0xa);
- boolean useTable1 = (info & 0x200) != 0;
- //boolean useTable1 = true;
- // Prende informazioni dalla piece table
- int complexOffset = LittleEndian.getInt(header, 0x1a2);
- //int complexOffset = LittleEndian.getInt(header);
- String tableName = null;
- if (useTable1) {
- tableName = "1Table";
- } else {
- tableName = "0Table";
- }
- DocumentEntry table = (DocumentEntry) fsys.getRoot().getEntry(tableName);
- byte[] tableStream = new byte[table.getSize()];
- din = fsys.createDocumentInputStream(tableName);
- din.read(tableStream);
- din.close();
- din = null;
- fsys = null;
- table = null;
- headerProps = null;
- int multiple = findText(tableStream, complexOffset, text);
- StringBuffer sb = new StringBuffer();
- int size = text.size();
- tableStream = null;
- for (int x = 0; x < size; x++) {
- WordTextPiece nextPiece = (WordTextPiece) text.get(x);
- int start = nextPiece.getStart();
- int length = nextPiece.getLength();
- boolean unicode = nextPiece.usesUnicode();
- String toStr = null;
- if (unicode) {
- toStr = new String(header, start, length * multiple, "UTF-16LE");
- } else {
- toStr = new String(header, start, length, "ISO-8859-1");
- }
- sb.append(toStr).append(" ");
- }
- return sb.toString();
- }
- private static int findText(byte[] tableStream, int complexOffset, ArrayList text)
- throws IOException {
- //actual text
- int pos = complexOffset;
- int multiple = 2;
- //skips through the prms before we reach the piece table. These contain data
- //for actual fast saved files
- while (tableStream[pos] == 1) {
- pos++;
- int skip = LittleEndian.getShort(tableStream, pos);
- pos += 2 + skip;
- }
- if (tableStream[pos] != 2) {
- throw new IOException("corrupted Word file");
- } else {
- //parse out the text pieces
- int pieceTableSize = LittleEndian.getInt(tableStream, ++pos);
- pos += 4;
- int pieces = (pieceTableSize - 4) / 12;
- for (int x = 0; x < pieces; x++) {
- int filePos =
- LittleEndian.getInt(tableStream, pos + ((pieces + 1) * 4) + (x * 8) + 2);
- boolean unicode = false;
- if ((filePos & 0x40000000) == 0) {
- unicode = true;
- } else {
- unicode = false;
- multiple = 1;
- filePos &= ~(0x40000000); //gives me FC in doc stream
- filePos /= 2;
- }
- int totLength =
- LittleEndian.getInt(tableStream, pos + (x + 1) * 4)
- - LittleEndian.getInt(tableStream, pos + (x * 4));
- WordTextPiece piece = new WordTextPiece(filePos, totLength, unicode);
- text.add(piece);
- }
- }
- return multiple;
- }
- public static void main(String[] args){
- WordExtractor w = new WordExtractor();
- POIFSFileSystem ps = new POIFSFileSystem();
- try{
- File file = new File("C://test.doc");
- InputStream in = new FileInputStream(file);
- String s = w.extractText(in);
- System.out.println(s);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- class WordTextPiece {
- private int _fcStart;
- private boolean _usesUnicode;
- private int _length;
- public WordTextPiece(int start, int length, boolean unicode) {
- _usesUnicode = unicode;
- _length = length;
- _fcStart = start;
- }
- public boolean usesUnicode() {
- return _usesUnicode;
- }
- public int getStart() {
- return _fcStart;
- }
- public int getLength() {
- return _length;
- }
- }
write word
- public boolean writeWordFile(String path, String content) {
- boolean w = false;
- try {
- // byte b[] = content.getBytes("ISO-8859-1");
- byte b[] = content.getBytes();
- ByteArrayInputStream bais = new ByteArrayInputStream(b);
- POIFSFileSystem fs = new POIFSFileSystem();
- DirectoryEntry directory = fs.getRoot();
- DocumentEntry de = directory.createDocument("WordDocument", bais);
- FileOutputStream ostream = new FileOutputStream(path);
- fs.writeFilesystem(ostream);
- bais.close();
- ostream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return w;
- }
写操作的代码还是有些问题:打开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
- 09:21
- 浏览 (12760)
- 论坛浏览 (14400)
- 评论 (11)
- 分类: 心得
- 收藏
- 相关推荐
评论
不过也问题比较多,不能区分单元格内内容的格式,或错误判断
我看POI对word支持不太够啊
poi-contrib-2.5.1-final-20040804.jar
poi-scratchpad-2.5.1-final-20040804.jar
能提供这几个包的下载吗?
原先我是使用nutch的word文本提取,但是相当大部分的中文word文档无法正确提取,到官方网站查看他们的解决方案,是这么说的“Document with 2-byte characters (that's how Chinese characters are probably stored) are not correctly handled by HWPF.”One more thing you need to consider: HWPF cannot handle "fast saved" Word files. If the documents you need to parse are "fast saved" this adds an extra level of complexity.
有点小问题,希望楼主有时间的时候帮忙大家修复一下,那就是有部分提取的文本前后有小方框的,我想应该是这些字符本不该被提取。