我们都知道要想利用java对office操作最常用的技术就应该是POI了,在这里本人就不多说究竟POI是什么和怎么用了。先说本人遇到的问题,不同于利用POI去向word文档以及excel文档去写入数据和向外导出数据并且保存到数据库中这些类似的操作,由于业务上的需要需要利用POI去读取word中的图片,并且去把图片去保存为一个file文件。查了Apache公司提供的api帮助文档,再网友的一些线索,本人也总结了几中对不同word版本(.doc或者是.docx结尾)对于文件中所含图片的操作方式,希望能对大家有所帮助。
闲话不多说,请看代码:
首先先是对于是.docx文件结尾的word文档中图片的操作:
package poi; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFPictureData; public class GetPics { public static void main(String[] args) { String path ="F:\\xx.docx"; File file = new File(path); try { FileInputStream fis = new FileInputStream(file); XWPFDocument document = new XWPFDocument(fis); XWPFWordExtractor xwpfWordExtractor = new XWPFWordExtractor(document); String text = xwpfWordExtractor.getText(); System.out.println(text); List<XWPFPictureData> picList = document.getAllPictures(); for (XWPFPictureData pic : picList) { System.out.println(pic.getPictureType() + file.separator + pic.suggestFileExtension() +file.separator+pic.getFileName()); byte[] bytev = pic.getData(); FileOutputStream fos = new FileOutputStream("d:\\"+pic.getFileName()); fos.write(bytev); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } }
指定word文件中的图片:
控制台输出的信息:
指定磁盘位置生成的图片文件:
然后就是对于是.doc结尾的word文档中图片的操作:
不同于高版本的操作类,这里用的就是专门对于03版本的word操作类:
package com.zjcx.read; import java.io.*; import java.util.*; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.model.PicturesTable; import org.apache.poi.hwpf.usermodel.CharacterRun; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.Range; public class ReadImg { public static void main(String[] args) throws Exception { new ReadImg().readPicture("F://test//test.doc"); } private void readPicture(String path)throws Exception{ FileInputStream in=new FileInputStream(new File(path)); HWPFDocument doc=new HWPFDocument(in); int length=doc.characterLength(); PicturesTable pTable=doc.getPicturesTable(); // int TitleLength=doc.getSummaryInformation().getTitle().length(); // System.out.println(TitleLength); // System.out.println(length); for (int i=0;i<length;i++){ Range range=new Range(i, i+1,doc); CharacterRun cr=range.getCharacterRun(0); if(pTable.hasPicture(cr)){ Picture pic=pTable.extractPicture(cr, false); String afileName=pic.suggestFullFileName(); OutputStream out=new FileOutputStream(new File("F:\\test\\"+UUID.randomUUID()+afileName)); pic.writeImageContent(out); } } } }
以下的生成结果同用高版本读取word中图片并且生成新图片的那几张效果图。
说完了对于不同版本的word文档中图片的操作,本人还遇到了创建word的业务。不同于我们利用流去生成一个txt文件,也不同与我们直接new一个File,然后在调用file的createNew这个方法。让我们来看看究竟利用POI代码和其他的代码来创建或者说是新建(其实只是最近程度的模仿生成一个word,但是肯定跟我们手动新建有所区别,具体有什么区别本人还是没有参透,如果有大牛看了如下的代码知道的话,希望能指点迷津~)一个word,闲话不多说,请看代码:
首先是第一种,创建.doc结尾的word文件。(在这里本人不在贴生成文件的效果图,大家试试即可)
package poi; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.POIFSFileSystem; public class GenWord03 { public static void main(String[] args) throws IOException { String path = "F:/"; String filename = "/123321.doc"; String content=""; byte[] b = content.getBytes("UTF-8"); ByteArrayInputStream bais = new ByteArrayInputStream(b); POIFSFileSystem poifs = new POIFSFileSystem(); DirectoryEntry dirEntry = poifs.getRoot(); dirEntry.createDocument("WordDocument", bais); FileOutputStream out = new FileOutputStream(path + filename); poifs.writeFilesystem(out); out.flush(); out.close(); bais.close(); } }
再者就是创建.docx结尾的word文件。
package poi; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; public class GenNewWord { public static void main(String[] args) throws IOException { String content = "要展示的内容"; String path = "F:/"; String filename = "/xxx.doc"; XWPFDocument doc = new XWPFDocument(); XWPFParagraph para= doc.createParagraph(); XWPFRun run = para.createRun(); run.setText(content); File file = new File(path + filename); FileOutputStream out = new FileOutputStream(file); doc.write(out); out.close(); } }
注:也许比较熟练POI操作的老手们来说,或许知道Apache公司提供的操作类中对于03版本的word文档操作是有限的,更多只是对于一个现有(已经存在)的文档操作,所以我们在各大网友的博客或者帖子中都会发现对于旧版本的word文档操作的代码开始处就是读取一个现有word的操作。而对于07版本(也就是.docx结尾的word文档)来说,则更加完善,开发者真正意义上可以完全利用POI去操作一个word文件的全部生命周期(也就是从无到有的过程)。这只是本人简略总结,有不足之处希望看到这篇博客的网友多多吐槽,多多交流。