本文采用Apache的 POI相关API,实现对Word的文档的解析。
实现将Word文件上传到Web服务器的指定地址,解析该Word文件并显示到浏览器。
<form id="mainForm" method="post" enctype="multipart/form-data" action="${basePath}/importWord">
...
<input class="tabSub" value="导 入" onclick="document.getElementById('mainForm').submit();" type="button" />
...
form>
存放上面JSP传递过来的参数。具体是由request解析数据到通用数据类,再从通用数据类存放到导入Word的参数类,便于管理和明确各类的功能。
public class ImportWordParamDto {
private String title;
private FileItem word;
public String getTitle() {return title;}
public void setTitle(String title) {this.title = title;}
public FileItem getWord() {return word;}
public void setWord(FileItem word) {this.word = word;}
}
此类是对业务处理后,结果数据的封装。
public class ImportWordResultDto {
private String title;
private String content;
private String msg;
public String getTitle() {return title;}
public void setTitle(String title) {this.title = title;}
public String getMsg() {return msg;}
public void setMsg(String msg) {this.msg = msg;}
public String getContent() {return content;}
public void setContent(String content) {this.content = content;}
}
根据提供业务参数:业务参数对象,实现 解析Word文件,将解析结果存入业务结果对象中,用于返回 。注意Word 03版 和 07版解析时应加以区分。
public class WordService {
public ImportWordResultDto imp(ImportWordParamDto dto) {
ImportWordResultDto result = new ImportWordResultDto();
result.setTitle(dto.getTitle());
HWPFDocument doc = null;
try {
// 先按照 03版的word文档来处理 .doc
doc = new HWPFDocument(dto.getWord().getInputStream());
// 注意把Word里的换行符改成html里的换行符
result.setContent(doc.getDocumentText().replace("\r", "
"));
} catch (OfficeXmlFileException oe) {
System.out.println("这可能是一个07版的word文件。");
} catch (IOException e) {
result.setMsg("这可能不是一个Word文件。");
return result;
} finally { // 注意释放资源
if (doc != null) {
try {
doc.close();
return result;
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 下面为 07版Word文档的解析
XWPFDocument docx = null;
try {
docx = new XWPFDocument(dto.getWord().getInputStream());
// 获取word的所有段落
List<XWPFParagraph> paragraphList = docx.getParagraphs();
// 循环遍历每个段落
StringBuilder content = new StringBuilder();
for (XWPFParagraph paragraph : paragraphList) {
content.append(paragraph.getText() + "
");
}
result.setContent(content.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (docx != null) {
try {
docx.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}
对以上实现的方法进行调用,实现业务逻辑,将结果数据返回给显示的JSP。
public class ImportWordServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(request)) {
ParamDto dto = RequestUtil.parseParam(request);
ImportWordParamDto paramDto = new ImportWordParamDto();
paramDto.setTitle(dto.getParamMap().get("title"));
paramDto.setWord(dto.getFileMap().get("word"));
WordService service = new WordService();
ImportWordResultDto resultDto = service.imp(paramDto);
request.setAttribute("result", resultDto);
}
request.getRequestDispatcher("/WEB-INF/JSP/importWordResult.jsp").forward(request, response);
}
}
使用EL表达式和JSTL协助展示数据。
<head>
<script type="text/javascript">
function bodyInit() { // 当有错误信息,显示错误信息
if('${result.msg}') {
alert('${result.msg}');
}
}
script>
head>
<body style="background: #e1e9eb;" onload="bodyInit();">
...
<table class="tab1">
<tr>
<td align="right" width="80">标题:td>
<td>${result.title}td>
tr>
<tr>
<td align="right" width="80">内容:td>
<td>${result.content}td>
tr>
table>
...
body>
业务参数类与导入时一致,注意将数据封装成二维的形式,方便于数据导入Word.
导出Word可向外留选择导出03版的还是07版的。
public class WordService {
// 依据模板导出 03版 word
public HWPFDocument export03(Map<String, String > replaceContent){
HWPFDocument doc = null;
try { // 先按照 03版的word模板来导出
doc = new HWPFDocument(new FileInputStream("C:\\template_03.doc"));
Range range = doc.getRange(); // 获得整个word文档
// 对整个word文档进行文本替换
for (Map.Entry<String, String> entry : replaceContent.entrySet()) {
range.replaceText(entry.getKey(), entry.getValue());
}
} catch (Exception e) {
return null;
}
return doc;
}
// 导出07版Word
public XWPFDocument export07(Map<String,String> replaceContent) {
XWPFDocument docx = null;
try {
docx = new XWPFDocument(new FileInputStream("C:\\template_07.docx"));
List<XWPFParagraph> paragraphList = docx.getParagraphs();
for(XWPFParagraph paragraph : paragraphList) {
// 07版在每个段落依据格式又切分成不同的小的单元runs
List<XWPFRun> runs = paragraph.getRuns();
for(XWPFRun run : runs) {
// 取出每个run中的文字,在每个run里进行替换
String str = run.getText(run.getTextPosition());
for(Map.Entry<String,String> entry : replaceContent.entrySet()) {
str = str.replace(entry.getKey(),entry.getValue());
}
// 改变每个run里的文字,从里的第0个字符开始替换
run.setText(str,0);
}
}
} catch (IOException e) {
return null;
}
return docx;
}
}
导出时一般不再服务器上备份Excel文件,如果需要也可以。
此Servlet没有跳转到重定向到其他界面,点击导出时的执行浏览器直接下载export.docx文件。
public class ExportWordServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
WordService service = new WordService();
Map<String, String> param = new HashMap<>();
param.put("${name}", request.getParameter("name"));
param.put("${age}", request.getParameter("age"));
param.put("${time}", request.getParameter("time"));
ServletOutputStream outputStream = response.getOutputStream();
// docx 07版的Word
if(request.getParameter("isDocx") != null && !"".equals(request.getParameter("isDocx"))) {
XWPFDocument docx = service.export07(param);
response.setHeader("Content-Disposition","attachment;filename=export.docx");
docx.write(outputStream);
docx.close();
} else {
// doc 03 版的Word
HWPFDocument doc = service.export03(param);
response.setHeader("Content-Disposition","attachment;filename=export.doc");
doc.write(outputStream);
doc.close();
}
outputStream.flush();
outputStream.close();
}
}