1.导入jar
<!-- 引入freeMarker的依赖包. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
@RequestMapping("/exportSummaryTimeWord")
@ResponseBody
public void exportMonthTimeWord(@RequestParam(value = "docDate", required = false) String docDate,
HttpServletRequest request, HttpServletResponse response) {
// 告诉浏览器用什么软件可以打开此文件
response.setHeader("content-Type", "application/msword");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename=Summary" + docDate + ".doc");
try {
//timemapdata 为map集合
/**Map
timemapdata = new HashMap();
timemapdata .put("nowYear",year+"");
timemapdata .put("month",docDate.split("-")[1]);
timemapdata .put("rankVospm25",rankVo2pm25List);
timemapdata .put("rankVospm10",rankVo2pm10List);
timemapdata .put("rankVoso3",rankVo2O3List);
**/
//exportTimeTemplateUtil为工具类 下面的下面 的代码
Template mybatisTemplate = exportTimeTemplateUtil.localTemplate();
mybatisTemplate.process(map, new OutputStreamWriter(response.getOutputStream()));
} catch (Exception e) {
e.printStackTrace();
}
}
package com.rate.web.compiled.util;
import com.rate.system.rate_system.config.BootdoConfig;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import java.io.*;
/**
* 检查导出word使用的模板文件
* 若无则创建
* @author szy
*/
@Component
public class ExportTimeTemplateUtil {
private static String TEMPLATE_NAME = "Time.ftl"; //模板名
private static String TEMPLATE_PATH = "/static/template"; //在项目的路径
/**
* 项目中的模板文件输入流
*/
private InputStream templateIs = null;
private Configuration cfg = null;
@Autowired
private BootdoConfig bootdoConfig;
/**
* 检查导出word功能模板文件并返回模板文件
*/
public Template localTemplate(){
Template template = null;
//系统中路径 这里获取自己项目路径 要改变
String localPath = bootdoConfig.getUploadPath();
File localPathDir = new File(localPath);
if(!localPathDir.exists()){
try{
localPathDir.mkdirs();
}catch (Exception e){
e.printStackTrace();
}
}
File file = new File(localPath + TEMPLATE_NAME);
InputStream fileIs = null;
try {
ClassPathResource resource = new ClassPathResource(TEMPLATE_PATH + "/" + TEMPLATE_NAME);
templateIs = resource.getInputStream();
if (file.exists()) {
fileIs = new FileInputStream(file);
if (fileIs.available() != templateIs.available()) {
writeTemplate(file);
initConfig(localPath);
}
} else {//文件不存在
writeTemplate(file);
initConfig(localPath);
}
if(cfg == null){
initConfig(localPath);
}
template = cfg.getTemplate(TEMPLATE_NAME, "UTF-8");
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (templateIs != null) {
templateIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileIs != null) {
fileIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return template;
}
/**
* 初始化freemaker模板配置
* @param filePath 本地模板文件路径
*/
private void initConfig(String filePath){
cfg = new Configuration(
Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
cfg.setDefaultEncoding("UTF-8");
File templateFile = new File(filePath);
try {
cfg.setDirectoryForTemplateLoading(templateFile);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写入模板文件到运行环境本地
* @param file 模板文件
* @throws IOException
*/
private void writeTemplate(File file) throws IOException {
OutputStream os = new FileOutputStream(file);
byte[] bs = new byte[1024];
int length = 0;
while ((length = templateIs.read(bs)) != -1){
os.write(bs, 0, length);
os.flush();
}
os.close();
}
}
前端接口
//导出月报表
function exportSummaryWord() {
var docDate = $("#docDate").val();
layer.confirm('确定要导出选中时间?', {
btn: ['确定', '取消']
},
function (index) {
layer.close(index);
layer.msg("请稍候...");
window.location.href = '/monthly/exportSummaryTimeWord?docDate=' + docDate
})
}
前端实例
<% layout('/include/default.html',{libs:["layer","layui"]}){ %>
<link href="/plugin/site/style.css" rel="stylesheet" />
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<style>
#searchContent{
}
#summaryDocContent{
border: #cbc0c0 1px solid;
width: 1000px;
/*height: 800px;*/
margin: auto;
box-shadow: 0 0 5px 1px #cbc0c0;
padding-bottom: 50px;
min-height: 900px;
}
.child-title{
font-size: 20px;
}
p{
padding: 15px;
font-size: 15px;
}
#docTitle{
color: #000;
text-align: center;
padding: 15px;
font-size: 30px;
margin-top: 15px;
}
#docDateText{
}
#docWindInfo{
padding: 0;
font-size: 17px;
}
#qkPolInfo, #qkPolInfo th{
text-align: center;
}
th, td{
display: table-cell;
}
#qkPolInfo td, #qkPolInfo th{
height: 70px;
min-height: 70px;
font-size: 16px;
}
#qkPolInfo th:nth-child(1),#qkPolInfo td:nth-child(1){
padding: 2px 5px;
word-break: break-all;
max-width: 160px;
}
.otherPolInfo, .otherPolInfo th{
text-align: center;
}
.otherPolInfo td, .otherPolInfo th{
height: 35px;
min-height: 35px;
font-size: 16px;
padding: 5px;
min-width: 40px;
}
.otherTitle{
margin-top: 20px;
font-size: 17px;
}
.limitValue>tbody>tr>td,
.limitValue>thead>tr>th{
width: 230px;
}
.limitValue>tbody>tr>td:nth-child(1),
.limitValue>thead>tr>th:nth-child(1){
width: 180px;
}
table{
width: 95%;
margin: 10px auto;
}
#standardInfo, #standardInfo th{
text-align: center;
}
#standardInfo td, #standardInfo th{
height: 30px;
min-height: 30px;
font-size: 16px;
}
#standardInfo th:nth-child(1),#standardInfo td:nth-child(1){
padding: 2px 5px;
word-break: break-all;
max-width: 160px;
}
#monthStandard, #monthStandard th{
text-align: center;
}
#monthStandard td, #monthStandard th{
height: 30px;
min-height: 30px;
font-size: 16px;
}
#monthStandard th:nth-child(1),#monthStandard td:nth-child(1){
padding: 2px 5px;
word-break: break-all;
max-width: 160px;
}
</style>
<div class="wrapper-content ">
<div class="ibox">
<div class="ibox-body">
<div id="searchContent">
<form action="/statement/dailySummary" type="GET">
<div class="form-group" style="line-height: 50px;vertical-align: middle;">
<input type="text"
placeholder="请选择时间" autocomplete="off"
id="docDate" name="docDate" class="form-control"
style="display: inline-block; vertical-align: middle; width: 150px;">
<!--
<input style="width: 150px;display: inline-block;vertical-align: middle;" class="form-control" type="text" id="docDate" name="docDate">
-->
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="getDocBody()" type="button"><i class="layui-icon"></i>查询</button>
<button class="layui-btn layui-btn-normal layui-btn-sm" onclick="exportSummaryWord()" type="button"><i class="layui-icon"></i>导出</button>
<br>
<label class="label-serch">数据源:</label>
<input type="radio" name="db" value="0" style="margin-left: 0px;width: 20px" checked/>
<label class="label-serch" style="margin-left: 0px;">标况</label>  
<input type="radio" name="db" style="margin-left: 0px;width: 20px" value="1"/>
<label class="label-serch" style="margin-left: 0px;" >实况</label>     
</div>
</form>
</div>
<div id="summaryDocContent" style="width: 1600px">
<p class="otherTitle" style="text-align: center">表一:<span id="t1"></span></p>
<table class="otherPolInfo" id="otherPolInfo1" border="1" >
<thead>
<tr>
<th colspan="4"><span id="f1"></span></th>
<th colspan="4"><span id="f2"></span></th>
</tr>
<tr>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="otherTitle" style="text-align: center">表二:<span id="t2"></span></p>
<table class="otherPolInfo" id="otherPolInfo2" border="1" >
<thead>
<tr>
<th colspan="4"><span id="f12"></span></th>
<th colspan="4"><span id="f22"></span></th>
</tr>
<tr>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p class="otherTitle" style="text-align: center">表三:<span id="t3"></span></p>
<table class="otherPolInfo" id="otherPolInfo3" border="1" >
<thead>
<tr>
<th colspan="4"><span id="f13"></span></th>
<th colspan="4"><span id="f23"></span></th>
</tr>
<tr>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
<th>排名</th>
<th>区域</th>
<th>站点</th>
<th>平均浓度 (μg/m³)</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<% } %>
<script src="/js/babel/polyfill.min.js"></script>
<script type="text/javascript" src="/js/summary/time.js"></script>
<script>
var nowDate = new Date();
layui.use('laydate', function () {
let laydate = layui.laydate;
laydate.render({
type : 'month',
elem: '#docDate',
format: 'yyyy-MM',
value: preDay(nowDate)
});
});
function preDay(nowDate) {
if (nowDate != null) {
return new Date(nowDate.getTime() - 24 * 60 * 60 * 1000);
}
}
let loadIndex;
function showLoad() {
loadIndex = layer.msg('请稍后...', {icon: 16,shade: [0.5, '#f5f5f5'],scrollbar: false,offset: 'auto', time:30000});
}
function closeLoad() {
layer.close(loadIndex);
}
String.prototype.replaceAll = function() {
if (!RegExp.prototype.isPrototypeOf("2019")) {
return this.replace(new RegExp("2019", (ignoreCase ? "gi": "g")), nowYear);
} else {
return this.replace("2019", nowYear);
}
}
</script>
js
$(function () {
setTimeout(function () {
getDocBody();
}, 300)
})
function getDocBody() {
showLoad();
let docDate = $("#docDate").val();
//let docDate = "2019-11";
let dataType = $("input[name='db']:checked").val();
$.ajax({
url: '/monthly/timeData',
type: 'get',
data: {docDate: docDate,
dataType:dataType},
success: function (res) {
var nowYear=res.nowYear;
var month=res.month;
rankVospm25 = res.rankVospm25;
rankVospm10 = res.rankVospm10;
rankVoso3 = res.rankVoso3 ;
$("#t1").html(nowYear+"年"+month+"月和1-"+month+"月乡镇(街办)PM10月平均浓度排名表");
$("#t2").html(nowYear+"年"+month+"月和1-"+month+"月乡镇(街办)PM25月平均浓度排名表");
$("#t3").html(nowYear+"年"+month+"月和1-"+month+"月乡镇(街办)臭氧月平均浓度排名表");
$("#f1").html( month+"月");$("#f2").html( "1-"+month+"月");
$("#f12").html( month+"月");$("#f22").html( "1-"+month+"月");
$("#f13").html( month+"月");$("#f23").html( "1-"+month+"月");
if (rankVospm25 && rankVospm25.length > 0) {
let body = $("#otherPolInfo2 tbody");
let tr = '';
for (var i=0 ; i<rankVospm25.length ; i++ ){
var sss=rankVospm25[i].pm25==null?"-":rankVospm25[i].pm25
var ss=rankVospm25[i].pm25Zh==null?"-":rankVospm25[i].pm25Zh
var s=i+1;
tr += "<tr>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVospm25[i].areaName +"</td>" +
"<td>"+rankVospm25[i].siteName +"</td>" +
"<td>"+sss+"</td>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVospm25[i].areaNameZh +"</td>" +
"<td>"+rankVospm25[i].siteNameZh +"</td>" +
"<td>"+ss +"</td>" +
"</tr>"
}
body.html(tr);
} else {
let bodyTr =
"<tr>" +
'<td colspan="10">暂无数据</td>' +
"</tr>";
$("#otherPolInfo2 tbody").html(bodyTr);
}
if (rankVospm10 && rankVospm10.length > 0) {
let body = $("#otherPolInfo1 tbody");
let tr = '';
for (var i=0 ; i<rankVospm10.length ; i++ ){
var ss=rankVospm10[i].pm10Zh==null?"-":rankVospm10[i].pm10Zh
var sss=rankVospm10[i].pm10==null?"-":rankVospm10[i].pm10
var s=i+1;
tr += "<tr>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVospm10[i].areaName +"</td>" +
"<td>"+rankVospm10[i].siteName +"</td>" +
"<td>"+sss +"</td>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVospm10[i].areaNameZh +"</td>" +
"<td>"+rankVospm10[i].siteNameZh +"</td>" +
"<td>"+ss+"</td>" +
"</tr>"
}
body.html(tr);
} else {
let bodyTr =
"<tr>" +
'<td colspan="10">暂无数据</td>' +
"</tr>";
$("#otherPolInfo1 tbody").html(bodyTr);
}
if (rankVoso3 && rankVoso3.length > 0) {
let body = $("#otherPolInfo3 tbody");
let tr = '';
for (var i=0 ; i<rankVoso3.length ; i++ ){
var sss= rankVoso3[i].o3eightHour==null?"-":rankVoso3[i].o3eightHour
var ss= rankVoso3[i].o3eightHourZh==null?"-":rankVoso3[i].o3eightHourZh
var s=i+1;
tr += "<tr>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVoso3[i].areaName +"</td>" +
"<td>"+rankVoso3[i].siteName +"</td>" +
"<td>"+ sss+"</td>" +
"<td>"+ s+"</td>" +
"<td>"+ rankVoso3[i].areaNameZh +"</td>" +
"<td>"+rankVoso3[i].siteNameZh +"</td>" +
"<td>"+ss +"</td>" +
"</tr>"
}
body.html(tr);
} else {
let bodyTr =
"<tr>" +
'<td colspan="10">暂无数据</td>' +
"</tr>";
$("#otherPolInfo3 tbody").html(bodyTr);
}
closeLoad();
},
error: function (e) {
console.error(e);
closeLoad();
}
});
}
//导出月报表
function exportSummaryWord() {
var docDate = $("#docDate").val();
layer.confirm('确定要导出选中时间?', {
btn: ['确定', '取消']
},
function (index) {
layer.close(index);
layer.msg("请稍候...");
window.location.href = '/monthly/exportSummaryTimeWord?docDate=' + docDate
})
}
Time.ftl 的形成
在word编辑好 转成xml格式 然后再编辑xml格式文档 然后改后缀名为ftl
例如 编辑文档