这是代码,一个工具类得调用
public class WordUtil {
/**
* 基于模板文件导出 word 文档,此方法主要是用来处理文档中需要替换的文本内容,对图片和表格无效
*
* @param templatePath
*模板文件的路径,要求路径中要包含全名,并且模板文件只能是 07 及以上格式,即 docx 的文件
* @param destFilePath
*导出文件的存放路径,包含文件名,例如,E:/test/小区公告.docx
* @param data
*用来替换文档中预定义的字符串,要求预定义的字符串与 data 中的 key 值要相同
*/
public static void exportWordByTemplate(String templatePath,
String destFilePath, Map<String, String>data) {
FileOutputStream out = null
XWPFDocument doc = null
try {
doc = new XWPFDocument(POIXMLDocument.openPackage(templatePath))
List<XWPFRun>listRun
List<XWPFParagraph>listParagraphs = doc.getParagraphs()
for (int i = 0i <listParagraphs.size()i++) {
listRun = listParagraphs.get(i).getRuns()
for (int j = 0j <listRun.size()j++) {
if (data.get(listRun.get(j).getText(0)) != null) {
String val = data.get(listRun.get(j).getText(0))
listRun.get(j).setText(val, 0)
}
}
}
File destFile = new File(destFilePath)
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs()
}
out = new FileOutputStream(destFilePath)
doc.write(out)
} catch (IOException e) {
e.printStackTrace()
} finally {
try {
if (out != null)
out.close()
} catch (IOException e) {
e.printStackTrace()
}
}
}
/**
* 基于模板文件导出 word 文档,该方法支持03格式,但是此方法只能保留文档内容,不能保留文档中的样式和图片,建议将模板使用 07 的格式保存
*
* @param templatePath
*模板文件的路径
* @param destFilePath
*导出文件的存放路径,包含文件名,例如,E:/test/小区公告.doc
* @param data
*用来替换文档中预定义的字符串,要求预定义的字符串与 data 中的 key 值要相同
*/
public static void export03WordByTemplate(String templatePath,
String destFilePath, Map<String, String>data) {
try {
WordExtractor doc = new WordExtractor(new FileInputStream(
templatePath))
String content = doc.getText()
for (String key : data.keySet()) {
content = content.replaceAll(key, data.get(key))
}
byte b[] = content.getBytes()
ByteArrayInputStream bais = new ByteArrayInputStream(b)
POIFSFileSystem fs = new POIFSFileSystem()
DirectoryEntry directory = fs.getRoot()
directory.createDocument("WordDocument", bais)
FileOutputStream ostream = new FileOutputStream(destFilePath)
fs.writeFilesystem(ostream)
bais.close()
ostream.close()
} catch (FileNotFoundException e) {
e.printStackTrace()
} catch (IOException e) {
e.printStackTrace()
}
}
public static void main(String[] args) throws Exception {
Map<String, String>maps = new HashMap<String, String>()
maps.put("appellation", "万达公寓业主:")
maps.put(
"main_body",
"输出的内容")
maps.put("date", "2013年1月23日")
exportWordByTemplate("E:/sss 2.docx", "E:/test/test.doc", maps)
}
}
"E:/sss 2.docx模板存放的地址。
E:/test/test.doc 新生成的地址。
用freemarker,可以自定义模板,然后用变量替换的方式。你可以看一下这篇文章(不是我写的)http://www.havenliu.com/java/514.html。其实word是支持html的, 你可以试试把.html的文件名改成.doc。
首先是action的createDoc方法:[java]
/**
* 通过HttpCient调用报告服务器的方法生成报告 DOC
*/
public String createDoc() throws Exception {
//定义放回成功与否的判断码
String prMsg=""
// 获取当前登录的用户
UserVo userVo = CommonUtils.getUserMessage()
//获取模版类型
docType = Struts2Utils.getParameter("docType")
//重新创建文档
String creatOrnot = Struts2Utils.getParameter("creatOrnot")
//获取组组编号参数
workgroupId = Struts2Utils.getParameter("workgroupId")
//获取评估用例实例ID参数
evtcaseInstId = Struts2Utils.getParameter("evtcaseInstId")
if(CommonUtils.isNotNull(docType)){
//获取项目Id
projectId = Struts2Utils.getParameter("projectId")
if(!CommonUtils.isNotNull(projectId)){
if(CommonUtils.isNotNull(this.getIdFromSession("PM_PROJECTID"))){
projectId = this.getIdFromSession("PM_PROJECTID").toString()
}else{
Struts2Utils.getRequest().setAttribute("msg", "请先选择项目!")
}
}
if(CommonUtils.isNotNull(projectId)){
prMsg = infoSystemDescService.downloadFileByUrl(projectId, userVo.getUserId(), workgroupId, evtcaseInstId, docType, creatOrnot)
}
}
return "docList"
}
注:在我贴出来的代码中,能看懂就行了,有些不用管他(可能是其他业务方面的判断),关于最后返回的prMsg---代表各种状态 主要表示成功与否或者是出错的信息。
接着我贴出service层的方法downloadFileByUrl
[java]
</pre><p></p><p></p><pre name="code" class="java"><pre name="code" class="java">/**
* 功能:
* 1.(生成报告文档)
* 2.保存指定URL的源文件到指定路径下
* @param projectId
* @param userId
* @param workgroupId
* @param evtcaseInstId
* @param docType
* @param creatOrnot
* @return
* @throws Exception
*/
@SuppressWarnings("deprecation")
public synchronized String downloadFileByUrl(String projectId,String userId,String workgroupId,String evtcaseInstId,String docType,String creatOrnot) throws Exception {
String msg = "1"//"1":默认为创建成功的提示信息 "2":标识创建失败
String srcUrl = "" //报告服务器的执行路径
HttpResponse response = null
FileOutputStream out = null
HttpClient httpclient = null
HttpGet httpget = null
long time1 = System.currentTimeMillis()
//获取保存后的路径
TProjDoc projDoc = projectDocDao.findFileByType(userId, Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId)
if(projDoc == null || (projDoc != null &&CommonUtils.isNotNull(creatOrnot) &&creatOrnot.equals("1"))){ //FT_任务编号_[FID]
try {
//获取报告服务器的执行路径
srcUrl = xmlPathDef.getActionUrl(docType, projectId,userId,workgroupId,evtcaseInstId)
HttpParams httpParams = new BasicHttpParams()
// 设置最大连接数
ConnManagerParams.setMaxTotalConnections(httpParams, 1)
// 设置获取连接的最大等待时间
//ConnManagerParams.setTimeout(httpParams, 6000)
// 设置每个路由最大连接数
ConnPerRouteBean connPerRoute = new ConnPerRouteBean(1)
ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute)
// 设置连接超时时间
HttpConnectionParams.setConnectionTimeout(httpParams, 6000)
// 设置读取超时时间
if(docType.toString().equals(XmlPathDef.SPOTTEST_DOC) &&docType.toString().equals(XmlPathDef.FTEST_DOC)){
HttpConnectionParams.setSoTimeout(httpParams, 2400000)
}else{
HttpConnectionParams.setSoTimeout(httpParams, 600000)
}
SchemeRegistry registry = new SchemeRegistry()
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80))
registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443))
ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, registry)
httpclient = new DefaultHttpClient(connectionManager, httpParams)
httpget = new HttpGet(srcUrl)
//执行返回
response = httpclient.execute(httpget)
//如果是本机既当服务器,又当报表服务器,那么就只生成一遍
String ipvalues = xmlPathDef.getRepUrl()
if(CommonUtils.isNotNull(ipvalues)){
if(ipvalues.indexOf(":") != -1){
ipvalues = ipvalues.substring(0,ipvalues.lastIndexOf(":"))
}
}
HttpEntity entity = response.getEntity()
//获取保存后的路径
projDoc = projectDocDao.findFileByType(userId,Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId)
String filePath = ""
if(projDoc != null)
filePath = projDoc.getPath()
if(CommonUtils.isNotNull(filePath)){
String basepath = XmlPathDef.getBasePath()
String outFilePath = (basepath + filePath).replaceAll("\\\\", "\\/")
XmlPathDef.isExists(outFilePath)
File wdFile = new File(outFilePath)
out = new FileOutputStream(wdFile)
int l
byte[] tmp = new byte[2048]
while ((l = instream.read(tmp)) != -1) {
out.write(tmp, 0, l)
}
out.flush()
out.close()
System.out.println("****************************** ")
System.out.println("")
System.out.println("*************** 恭喜! 报告创建成功 结束 ***************")
System.out.println("")
}else{
msg = "8"//说明word创建成功,但是数据没有保存成功
response = null
}
}else{
msg = "2"
}
} catch (ClientProtocolException e) {
msg = "7"
e.printStackTrace()
} catch (IOException e) {
msg = "7"
logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时" + e.getMessage())
e.printStackTrace()
}finally{
if(out!=null){
try {
out.close()
} catch (IOException e) {
msg = "7"
logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时" + e.getMessage())
e.printStackTrace()
}
}
}
}
long time2 = System.currentTimeMillis()
long numTime = time2 - time1
if(docType.toString().equals(XmlPathDef.SPOTTEST_DOC) &&docType.toString().equals(XmlPathDef.FTEST_DOC)){
if(numTime >= 2401000){
msg = "9"
}
}else{
if(numTime >= 601000){
msg = "9"
}
}
System.out.println("")
String loggerinfo = "********* 报告类型为 :" + docType + " 执行时间为: " + (time2 - time1) /1000 + " 秒!***************"
System.out.println(loggerinfo)
System.out.println("")
System.out.println("*****************************")
logger.info(loggerinfo)
return msg
}