最近在项目中遇到了,根据用户填写的信息,自动填写到word模板中,可以从手机中导出完整的word,并可以在应用中进行预览的需求。
准备:
1.自己编写好的word模板
用$content$ 做为要被替换的标识。具体模板样式可以根据需求编写。这里提醒必须是以 .doc 结尾的文档。
2.poi 库
网上其实编写的生成word 文档 和 预览基本都都是一样的,而且也是对的。我也是按照网上的写的,难点在于正确的这两个库的寻找。word文档的生成基本不会有问题,在预览word 也就是根据word 生成html 格式的时候很容易出现一个异常
wordToHtmlConverter.processDocument(wordDocument) 这一行报空指针异常,和代码没关系,是这里面库的问题。
文章末会提供靠谱好用的这两个库的下载地址
功能1:将数据填入word 模板
private static final String newPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/doc/test.doc"; private static final String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/doc";
public void Save() { try { //从assets读取我们的Word模板 InputStream is = getAssets().open("讯问笔录模板.doc"); //创建生成的文件 File old = new File(newPath); File newFile=null; if(old.exists()){ old.delete(); newFile=new File(newPath); }else{ newFile=new File(newPath); } Map<String, String> map = new HashMap<String, String>(); map.put("$Address$", "测试机构"); map.put("$Number$", "6"); map.put("$Name$", "张三"); map.put("$DateStar$", "2009年3月15日15点03分"); map.put("$DateEnd$", "2009年3月15日16点00分"); map.put("$Age$", "28"); Log.e(TAG, "Save: " ); writeDoc(is, newFile, map); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "Save: "+e.toString() ); } }
/** * newFile 生成文件 * map 要填充的数据 */ public void writeDoc(InputStream in, File newFile, Map<String, String> map) { try { File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } HWPFDocument hdt = new HWPFDocument(in); // PdfDocument hd=new PdfDocument(); // Fields fields = hdt.getFields(); // 读取word文本内容 Range range = hdt.getRange(); // System.out.println(range.text()); // 替换文本内容 Log.e(TAG, "writeDoc: "+file.getAbsolutePath() ); for (Map.Entry<String, String> entry : map.entrySet()) { range.replaceText(entry.getKey(), entry.getValue()); } ByteArrayOutputStream ostream = new ByteArrayOutputStream(); FileOutputStream out = new FileOutputStream(newFile, true); hdt.write(ostream); // 输出字节流 out.write(ostream.toByteArray()); out.close(); ostream.close(); Log.e(TAG, "writeDoc: successs " ); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "writeDoc: 1"+e.toString()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "writeDoc: 2"+e.toString()); } }
这样就完成了 数据填写入 word 模板,并可以导出来。这一步基本都会成功。
功能二:word 转html 预览
//文件存储位置 private String docPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/doc/"; //文件名称 private String docName = "test.doc"; //html文件存储位置 private String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/doc/";
try { Word2003ToHtml(); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "onCreate: 1"+e.toString() ); }
webView = (WebView) this.findViewById(R.id.office); WebSettings webSettings = webView.getSettings(); webSettings.setLoadWithOverviewMode(true); webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); webView.getSettings().setDisplayZoomControls(false); webView.loadUrl("file:///" + savePath + name + ".html");
public void Word2003ToHtml() throws IOException, TransformerException, ParserConfigurationException { String filepath = docPath; final String imagepath = docPath; String fileName = "test.doc"; String htmlName = "test.html"; final String file = filepath + fileName; InputStream input = new FileInputStream(new File(file)); HWPFDocument wordDocument = new HWPFDocument(input); WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); //设置图片存放的位置 wordToHtmlConverter.setPicturesManager(new PicturesManager() { public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) { File imgPath = new File(imagepath); if (!imgPath.exists()) {//图片目录不存在则创建 imgPath.mkdirs(); } File file = new File(imagepath + suggestedName); try { OutputStream os = new FileOutputStream(file); os.write(content); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return imagepath + suggestedName; } }); wordToHtmlConverter.processDocument(wordDocument); Document htmlDocument = wordToHtmlConverter.getDocument(); File htmlFile = new File(filepath + htmlName); OutputStream outStream = new FileOutputStream(htmlFile); //也可以使用字符数组流获取解析的内容 // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // OutputStream outStream = new BufferedOutputStream(baos); DOMSource domSource = new DOMSource(htmlDocument); StreamResult streamResult = new StreamResult(outStream); TransformerFactory factory = TransformerFactory.newInstance(); Transformer serializer = factory.newTransformer(); serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty(OutputKeys.METHOD, "html"); serializer.transform(domSource, streamResult); //也可以使用字符数组流获取解析的内容 // String content = baos.toString(); // System.out.println(content); // baos.close(); outStream.close(); }
代码基本和别人也都一样,就是在poi库的正确性。
我这里真实可用的poi-3.9库 下载地址