1.后端实现controller
//@Anonymous
@PostMapping("/export/activity")
public AjaxResult activityWord(@RequestBody BluehubContract bluehubContract)
{
return success(bluehubContractService.activityWord(bluehubContract));
}
2.主要流程
/**
* 导出活动合同
*/
@Override
public String activityWord(BluehubContract bluehubContract){
BluehubContract a = new BluehubContract();
a.setContractCode(bluehubContract.getContractCode());
String roomName = selectBluehubContractList(a).get(0).getRoomName();
BluehubContract contract = selectBluehubContractByContractCode(bluehubContract.getContractCode());
List<BluehubContractCostDetail> costList = contract.getBluehubContractCostDetailList();
List<BluehubContractTimeDetail> timeList = contract.getBluehubContractTimeDetailList();
// 模板文件路径
String templatePath = this.getClass().getClassLoader().getResource("template/BlueHubActivity.docx").getPath();
// 输出文件路径
String outputPath = RuoYiConfig.getDownloadPath()+bluehubContract.getContractCode()+".docx";
//准备time数据
String time_detail_ymd_date = "";
String time_detail_ymd_time = "";
if (null != timeList) {
for (BluehubContractTimeDetail time : timeList) {
time_detail_ymd_date = time_detail_ymd_date + DateUtils.dateTime(time.getStartTime()) + "-" + DateUtils.dateTime(time.getEndTime()) + "\r";
time_detail_ymd_time = time_detail_ymd_time + DateUtils.dateTimeHMS(time.getStartTime()) + "-" + DateUtils.dateTimeHMS(time.getEndTime()) + "\r";
}
}
//准备cost数据
String cost_detail_4 = "";
String cost_detail_5 = "";
String cost_detail_6 = "";
String cost_detail_7 = "";
if (null != costList) {
for (BluehubContractCostDetail cost : costList) {
Object price;
if (null == cost.getPrice()) {
price = " ";
} else {
price = cost.getPrice();
}
if ("4".equals(cost.getCostType())) {
if (StringUtils.isEmpty(cost.getRemark())) {
cost_detail_4 = cost_detail_4 + "人民币[" + price + " ]元/天" + "\r";
} else {
cost_detail_4 = cost_detail_4 + "人民币[" + price + " ]元/天(" + cost.getRemark() + ")" + "\r";
}
}
if ("5".equals(cost.getCostType())) {
if (StringUtils.isEmpty(cost.getRemark())) {
cost_detail_5 = cost_detail_5 + "人民币[" + price + " ]元/小时" + "\r";
} else {
cost_detail_5 = cost_detail_5 + "人民币[" + price + " ]元/小时(" + cost.getRemark() + ")\r";
}
}
if ("6".equals(cost.getCostType())) {
if (StringUtils.isEmpty(cost.getRemark())) {
cost_detail_6 = cost_detail_6 + "人民币[" + price + " ]元/时" + "\r";
} else {
cost_detail_6 = cost_detail_6 + "人民币[" + price + " ]元/时(" + cost.getRemark() + ")\r";
}
}
if ("7".equals(cost.getCostType())) {
if (StringUtils.isEmpty(cost.getRemark())) {
cost_detail_7 = cost_detail_7 + "人民币[" + price + " ]元" + "\r";
} else {
cost_detail_7 = cost_detail_7 + "人民币[" + price + " ]元(" + cost.getRemark() + ")\r";
}
}
}
}
// 填充数据
Map<String, String> data = new HashMap<>();
data.put("contract", contract.getContractName());
data.put("Activity", contract.getActivityName());
data.put("location", roomName);
data.put("people", contract.getPeople().toString());
data.put("remark", contract.getRemark());
data.put("date", time_detail_ymd_date);
data.put("time", time_detail_ymd_time);
data.put("SiteCost", cost_detail_4);
data.put("SetCost", cost_detail_5);
data.put("OverCost", cost_detail_6);
data.put("SafeCost", cost_detail_7);
data.put("total_price", contract.getTotalPrice().toString());
try {
// 加载模板
XWPFDocument doc = new XWPFDocument(new FileInputStream(templatePath));
// 替换文本
replaceInDoc(doc, data);
// 写入输出文件
FileOutputStream out = new FileOutputStream(outputPath);
doc.write(out);
out.close();
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
return bluehubContract.getContractCode()+".docx";
}
private static void replaceInDoc(XWPFDocument doc, Map<String, String> data) {
// 遍历文档中的所有段落
for (XWPFParagraph para : doc.getParagraphs()) {
replaceInPara(para, data);
}
// 遍历文档中的所有表格
for (XWPFTable table : doc.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph cellPara : cell.getParagraphs()) {
replaceInPara(cellPara, data);
}
}
}
}
}
private static void replaceInPara(XWPFParagraph para, Map<String, String> data) {
List<XWPFRun> runs = para.getRuns();
if (runs != null) {
for (int i = 0; i < runs.size(); i++) {
XWPFRun r = runs.get(i);
String runText = r.getText(0);
if (runText != null && !runText.isEmpty()) {
for (Map.Entry<String, String> entry : data.entrySet()) {
String replace = entry.getKey();
String replaceWith = entry.getValue();
if (runText.contains(replace)) {
String[] split = replaceWith.split("\r");
if (split.length > 1) {
for (int j = 0; j < split.length; j++) {
if (j == 0) {
r.setText(runText.replace(replace, split[0]), 0);
} else {
r.setText(split[j]);
}
r.addBreak(BreakType.TEXT_WRAPPING);
}
} else {
r.setText(runText.replace(replace, replaceWith), 0);
}
}
}
}
}
}
}
至此,可以返回给前端生成的文件名
3.前端调用下载
activityExport(row){
const queryParams = this.queryParams;
this.$confirm('是否确认导出word文档?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
//this.exportLoading = true;
return activity({"contractCode":row.contractCode});
}).then(response => {
console.log(response)
this.downloadFile(response.msg);
// this.exportLoading = false;
}).catch(() => {});
}
4.全局挂载新的下载文件方法
downloadFile() {
this.dialogVisible = true
this.showFileName = true
this.operationType = 'downloadFile'
},
main.js新增
import { download,downloadFile } from '@/utils/request'
Vue.prototype.downloadFile = downloadFile
request.js
// 通用下载方法
export function downloadFile(fileName) {
window.location.href = baseURL + "common/download?fileName=" + encodeURI(fileName) + "&delete=" + false;
}
5.模板
6.注意事项
(1)common/download接口需要放行
(2)word文档中的key要一次打出来,不能断开,否则会被runs识别为两个部分
(3)word换行要使用break方法
(4)获取模板不要使用绝对路径,模板名称最好不要带中文