最近在项目中遇到了,根据用户填写的信息,自动填写到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库 下载地址
https://download.csdn.net/download/rfgreeee/11151882