文章目錄
- 前言
- 一、任務描述以及前期準備
- 1.任務描述
- 2.前期準備
- 二、撰寫java代碼轉成word檔案
- 1.小服務代碼
- 2.工具類代碼
- 3.jsp頁面代碼
- 三、word簽名和匯出pdf
- 1.簽名
- 2.匯出pdf
- 四、最后展示效果
- 總結
前言
本篇文章主要本人接到的一個緊急任務,時間緊任務重,完成的比較倉促,后續還需改善,最主要是感覺之前沒有怎么接觸過,所以分享出來,供大家參考一下,
一、任務描述以及前期準備
1.任務描述
是將資料庫中的每個表的欄位匯出,生成word檔案,并且可以簽字和匯出,
2.前期準備
1.首先在Eclipse Java EE版中新建一個Dynamic Web Project,專案結構如下圖所示

需要向專案中加入freemarker的JAR檔案,可以通過下面的鏈接獲得Freemarker的最新版本:
http://freemarker.org/freemarkerdownload.html
2.然后打開word檔案,建立自己所需要的模板,然后將word保存為XML這里可能出現的一個問題就是需要填入的內容放到占位符的時候可能會出現字符分離的情況,所以建議先將需要用
占
位
符
的
地
方
用
中
文
寫
在
w
o
r
d
里
然
后
保
存
為
X
M
L
的
格
式
再
打
開
X
M
L
對
需
要
用
{}占位符的地方用中文寫在word里然后保存為XML的格式再打開XML對需要用
占位符的地方用中文寫在word里然后保存為XML的格式再打開XML對需要用{}占位符的地方進行替換,這樣就避免了字符分離的情況,

這里我使用的一個軟體foxe(按F8可以對XML進行格式化,然后再對XML進行編輯,)
修改過后另存為resume.ftl模板檔案,如下圖:

二、撰寫java代碼轉成word檔案
1.小服務代碼
這里用的是Servlet(也可以是Struts2的Action、Spring MVC的Controller等)
小服務代碼如下:
package com.lovo.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.lovo.util.WordGenerator;
/**
* Servlet implementation class MyServlet
*/
@WebServlet("/saveDocServlet")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Map<String, Object> map = new HashMap<String, Object>();
Enumeration<String> paramNames = req.getParameterNames();
// 通過回圈將表單引數放入鍵值對映射中
while(paramNames.hasMoreElements()) {
String key = paramNames.nextElement();
String value = req.getParameter(key);
map.put(key, value);
}
// 提示:在呼叫工具類生成Word檔案之前應當檢查所有欄位是否完整
// 否則Freemarker的模板殷勤在處理時可能會因為找不到值而報錯 這里暫時忽略這個步驟了
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 呼叫工具類WordGenerator的createDoc方法生成Word檔案
file = WordGenerator.createDoc(map, "resume");
fin = new FileInputStream(file);
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/msword");
// 設定瀏覽器以下載的方式處理該檔案默認名為resume.doc
resp.addHeader("Content-Disposition", "attachment;filename=resume.doc");
out = resp.getOutputStream();
byte[] buffer = new byte[512]; // 緩沖區
int bytesToRead = -1;
// 通過回圈將讀入的Word檔案的內容輸出到瀏覽器中
while((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete(); // 洗掉臨時檔案
}
}
}
2.工具類代碼
工具類代碼如下:
package com.lovo.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class WordGenerator {
private static Configuration configuration = null;
private static Map<String, Template> allTemplates = null;
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(WordGenerator.class, "/com/lovo/ftl");
allTemplates = new HashMap<>(); // Java 7 鉆石語法
try {
allTemplates.put("resume", configuration.getTemplate("resume.ftl"));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private WordGenerator() {
throw new AssertionError();
}
public static File createDoc(Map<?, ?> dataMap, String type) {
String name = "temp" + (int) (Math.random() * 100000) + ".doc";
File f = new File(name);
Template t = allTemplates.get(type);
try {
// 這個地方不能使用FileWriter因為需要指定編碼型別否則生成的Word檔案會因為有無法識別的編碼而無法打開
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
}
3.jsp頁面代碼
jsp頁面代碼如下:

這里不方便拿出來,就截個圖吧,
三、word簽名和匯出pdf
1.簽名
這里說明一下,簽名主要是前臺完成,所以js寫的比較多
代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<link rel="stylesheet" href="./css/mui.min.css" />
<link rel="stylesheet" href="./css/reset.css" />
<link rel="stylesheet" href="./css/base.css" />
<!-- <link rel="stylesheet" href="./css/mui.picker.min.css" /> -->
<link rel="stylesheet" href="./css/HN_Sign.css"/>
<title>簽名</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body id="qz_parents">
<div class="canvasDiv">
<!--<div id="editing_area">-->
<canvas width="600" height="250" id="canvasEdit"></canvas>
<!--</div>-->
</div>
<div class="imgDiv">
<span id="sign_show"></span>
</div>
<!--<a class="return">-->
<!--<img src="../../images/Public_icon_sign_back.png"/>-->
<!--</a>-->
<p><img class="" src="image/xzk.png"/><span>本人已知悉并認可電子簽名效力等同書面形式簽字</span></p>
<div class="btnDiv">
<a id="sign_clear" class="clearBtn">清除</a>
<button id="sign_ok" class="okBtn" disabled>確認</button>
<button id="cancel" class="cancel">取消</button>
</div>
<script type="text/javascript" src="./js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="./js/mui.js"></script>
<!-- <script type="text/javascript" src="../../static/js/mui.picker.min.js"></script> -->
<script type="text/javascript" src="./js/bzyd.common.js"></script>
<script type="text/javascript" src="./js/rem.js"></script>
<script type="text/javascript" src="./js/html2canvas.js"></script>
<script type="text/javascript" src="./js/HN_esign.js"></script>
<script>
$(function() {
//初始化動作,根據DOM的ID不同進行自定義,如果不寫則內部默認取這四個
$().esign("canvasEdit", "sign_show", "sign_clear", "sign_ok");
$('p').width($('.canvasDiv').width());
$('canvas').attr('height',$('.canvasDiv').height()).attr('width',$('.canvasDiv').width());
$('p').children('img').click(function(){
$(this).toggleClass('check');
if($(this).hasClass('check')){
$(this).attr('src','image/xzk.png');
$('#sign_ok').removeAttr('disabled');
} else{
$(this).attr('src','image/xzk.png');
$('#sign_ok').attr('disabled','disabled');
}
});
$('#cancel').click(function(){
window.history.go(-1);
});
});
</script>
</body>
</html>
2.匯出pdf
匯出pdf也是挺麻煩的,不解釋了,上代碼,,,
代碼如下:
package com.sgcc.am.freemarkerwork1.util;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class DocumentHandler {
//Configuration存盤一些全域常量和常用設定
private Configuration configuration = null;
//建構式生成實體并設定編碼
public DocumentHandler() {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
}
/**
* 匯出word檔案,匯出到本地
* @param tempName,要使用的模板
* @param docName,匯出檔案名稱
* @param dataMap,模板中變數資料
* @param outFile,輸出檔案路徑
*/
public boolean exportDoc(String tempName,Map<?, ?> dataMap,File outFile) {
boolean status = false;
// 設定模本裝置方法和路徑,FreeMarker支持多種模板裝載方法,可以重servlet,classpath,資料庫裝載,
configuration.setClassForTemplateLoading(this.getClass(), "com/sgcc/am/freemarkerwork1/ftl");
Template t = null;
try{
// tempName.ftl為要裝載的模板
t = configuration.getTemplate(tempName+".ftl");
t.setEncoding("utf-8");
} catch (IOException e) {
e.printStackTrace();
}
Writer out = null;
try{
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
status = true;
}catch(Exception e1) {
e1.printStackTrace();
}
try{
t.process(dataMap, out);
out.close();
}catch(TemplateException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return status;
}
/**
* 匯出word檔案,回應到請求端
* @param tempName,要使用的模板
* @param docName,匯出檔案名稱
* @param dataMap,模板中變數資料
* @param resp,HttpServletResponse
*/
public boolean exportDoc(String tempName, String docName, Map<?, ?> dataMap, HttpServletResponse resp) {
boolean status = false;
ServletOutputStream sos = null;
InputStream fin = null;
if (resp != null) {
resp.reset();
}
// 設定模本裝置方法和路徑,FreeMarker支持多種模板裝載方法,可以重servlet,classpath,資料庫裝載,引數2為模板路徑
configuration.setClassForTemplateLoading(this.getClass(), "com/sgcc/am/freemarkerwork1/ftl");
Template t = null;
try {
// tempName.ftl為要裝載的模板
t = configuration.getTemplate(tempName + ".ftl");
t.setEncoding("utf-8");
} catch (IOException e) {
e.printStackTrace();
}
// 輸出檔案路徑及名稱 ,以臨時檔案的形式匯出服務器,再進行下載
String name = "temp" + (int) (Math.random() * 100000) + ".doc";
File outFile = new File(name);
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
status = true;
} catch (Exception e1) {
e1.printStackTrace();
}
try {
t.process(dataMap, out);
out.close();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
fin = new FileInputStream(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 檔案下載
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/msword");
try {
docName = new String(docName.getBytes("UTF-8"), "ISO-8859-1");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
resp.setHeader("Content-disposition", "attachment;filename=" + docName + ".doc");
try {
sos = resp.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
byte[] buffer = new byte[512]; // 緩沖區
int bytesToRead = -1;
// 通過回圈將讀入的Word檔案的內容輸出到瀏覽器中
try {
while ((bytesToRead = fin.read(buffer)) != -1) {
sos.write(buffer, 0, bytesToRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null)
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
if (sos != null)
try {
sos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outFile != null)
outFile.delete(); // 洗掉臨時檔案
}
return status;
}
}
四、最后展示效果


總結
主要是任務急,沒有具體整理代碼,大家僅供參考,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/225364.html
標籤:其他
