VUE动态生成word的实现


Posted in Javascript onJuly 26, 2020

不废话,直接上代码。

前端代码:

<template>
  <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="110">
    <FormItem label="项目(全称):" prop="orgName">
      <Input v-model="formValidate.orgName" placeholder="请输入项目名称"></Input>
    </FormItem>
    <FormItem label="申请人:" prop="applyName" >
      <Input v-model="formValidate.applyName" placeholder="请输入申请人"></Input>
    </FormItem>
    <FormItem label="电话:" prop="applyPhone">
      <Input v-model="formValidate.applyPhone" placeholder="请输入电话"></Input>
    </FormItem>
    <FormItem label="生效日期:" style="float: left">
      <Row>
        <FormItem prop="startDate">
          <DatePicker type="date" format="yyyy-MM-dd" placeholder="请选择生效日期" v-model="formValidate.startData"></DatePicker>
        </FormItem>
      </Row>
    </FormItem>
    <FormItem label="失效日期:">
      <Row>
        <FormItem prop="endDate">
          <DatePicker type="date" format="yyyy-MM-dd" placeholder="请选择失效日期" v-model="formValidate.endData"></DatePicker>
        </FormItem>
      </Row>
    </FormItem>
    <FormItem label="备注:" prop="vmemo">
      <Input v-model="formValidate.vmemo" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="备注"></Input>
    </FormItem>
    <FormItem>
      <Button type="primary" @click="handleSubmit('formValidate')">生成申请单</Button>
    </FormItem>
  </Form>
</template>
<script>
  import axios from 'axios';
  export default {
    data () {
      return {
        formValidate: {
          orgName: '',
          applyName: '',
          applyPhone: '',
          startDate: '',
          endDate: '',
          vmemo:''
        },
        ruleValidate: {
          orgName: [
            { required: true, message: '项目名称不能为空!', trigger: 'blur' }
          ],
          applyName: [
            { required: true, message: '申请人不能为空!', trigger: 'blur' }
          ],
          applyPhone: [
            { required: true, message: '电话不能为空!', trigger: 'change' }
          ],
          startDate: [
            { required: true, type: 'date', message: '请输入license有效期!', trigger: 'change' }
          ],
          endDate: [
            { required: true, type: 'date', message: '请输入license有效期!', trigger: 'change' }
          ],
        }
      }
    },
    methods: {
      handleSubmit (name) {
        this.$refs[name].validate((valid) => {
          if (valid) {
            axios({
              method: 'post',
              url: this.$store.getters.requestNoteUrl,
              data: this.formValidate,
              responseType: 'blob'
            }).then(res => {
              this.download(res.data);
            });
          }
        });
      },
      download (data) {
        if (!data) {
          return
        }
        let url = window.URL.createObjectURL(new Blob([data]))
        let link = document.createElement('a');
        link.style.display = 'none';
        link.href = url;
        link.setAttribute('download', this.formValidate.orgName+'('+ this.formValidate.applyName +')'+'-申请单.doc');
        document.body.appendChild(link);
        link.click();
      }
    }
  }
</script>

后台:

/**
 * 生成license申请单
 */
@RequestMapping(value = "/note", method = RequestMethod.POST)
public void requestNote(@RequestBody LicenseRequestNoteModel noteModel, HttpServletRequest req, HttpServletResponse resp) {
  File file = null;
  InputStream fin = null;
  ServletOutputStream out = null;
  try {
    req.setCharacterEncoding("utf-8");
    file = ExportDoc.createWord(noteModel, req, resp);
    fin = new FileInputStream(file);
    resp.setCharacterEncoding("utf-8");
    resp.setContentType("application/octet-stream");
    resp.addHeader("Content-Disposition", "attachment;filename="+ noteModel.getOrgName()+"申请单.doc");
    resp.flushBuffer();
    out = resp.getOutputStream();
    byte[] buffer = new byte[512]; // 缓冲区
    int bytesToRead = -1;
    // 通过循环将读入的Word文件的内容输出到浏览器中
    while ((bytesToRead = fin.read(buffer)) != -1) {
      out.write(buffer, 0, bytesToRead);
    }
 
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    try {
      if (fin != null) fin.close();
      if (out != null) out.close();
      if (file != null) file.delete(); // 删除临时文件
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
 
}
public class ExportDoc {
  private static final Logger logger = LoggerFactory.getLogger(ExportDoc.class);
  // 针对下面这行有的报空指针,是目录问题,我的目录(项目/src/main/java,项目/src/main/resources),这块也可以自己指定文件夹
  private static final String templateFolder = ExportDoc.class.getClassLoader().getResource("/").getPath();
  private static Configuration configuration = null;
  private static Map<String, Template> allTemplates = null;
 
  static {
    configuration = new Configuration();
    configuration.setDefaultEncoding("utf-8");
 
    allTemplates = new HashedMap();
    try {
      configuration.setDirectoryForTemplateLoading(new File(templateFolder));
      allTemplates.put("resume", configuration.getTemplate("licenseApply.ftl"));
    } catch (IOException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
 
 
  public static File createWord(LicenseRequestNoteModel noteModel, HttpServletRequest req, HttpServletResponse resp) throws Exception {
    File file = null;
 
    req.setCharacterEncoding("utf-8");
    // 调用工具类WordGenerator的createDoc方法生成Word文档
    file = createDoc(getData(noteModel), "resume");
    return file;
  }
 
 
  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;
  }
 
 
  private static Map<String, Object> getData(LicenseRequestNoteModel noteModel) throws Exception {
 
    Map<String, Object> map = new HashedMap();
    map.put("orgName", noteModel.getOrgName());
    map.put("applyName", noteModel.getApplyName());
    map.put("applyPhone", noteModel.getApplyPhone());
    map.put("ncVersion", noteModel.getNcVersionModel());
    map.put("environment", noteModel.getEnvironmentModel());
    map.put("applyType", noteModel.getApplyTypeModel());
 
    map.put("mac", GetLicenseSource.getMacId());
    map.put("ip", GetLicenseSource.getLocalIP());
    map.put("startData", DateUtil.Date(noteModel.getStartData()));
    map.put("endData", DateUtil.Date(noteModel.getEndData()));
    map.put("hostName", noteModel.getHostNames());
    map.put("vmemo", noteModel.getVmemo());
    return map;
  }
 
}
public class LicenseRequestNoteModel{
  private String orgName = null;
 
  private String applyName = null;
 
  private String applyPhone = null;
  
  private String ncVersionModel= null;
 
  private String environmentModel= null;
 
  private String applyTypeModel= null;
 
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  private Date startData= null;
 
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  private Date endData= null;
 
  private String[] hostName= null;
 
  private String vmemo= null;
 
  private String applyMAC= null;
 
  private String applyIP= null;
 
  public String getOrgName() {
    return orgName;
  }
 
  public void setOrgName(String projectName) {
    this.orgName = projectName;
  }
 
  public String getApplyName() {
    return applyName;
  }
 
  public void setApplyName(String applyName) {
    this.applyName = applyName;
  }
 
  public String getApplyPhone() {
    return applyPhone;
  }
 
  public void setApplyPhone(String applyPhone) {
    this.applyPhone = applyPhone;
  }
 
  public String getNcVersionModel() {
    return ncVersionModel;
  }
 
  public void setNcVersionModel(String ncVersionModel) {
    this.ncVersionModel = ncVersionModel;
  }
 
  public String getEnvironmentModel() {
    return environmentModel;
  }
 
  public void setEnvironmentModel(String environmentModel) {
    this.environmentModel = environmentModel;
  }
 
  public String getApplyTypeModel() {
    return applyTypeModel;
  }
 
  public void setApplyTypeModel(String applyTypeModel) {
    this.applyTypeModel = applyTypeModel;
  }
 
  public Date getStartData() {
    return startData;
  }
 
  public void setStartData(Date startData) {
    this.startData = startData;
  }
 
  public Date getEndData() {
    return endData;
  }
 
  public void setEndData(Date endData) {
    this.endData = endData;
  }
 
  public String[] getHostName() {
    return hostName;
  }
 
  public String getHostNames() {
    return StringUtils.join(this.hostName,",");
  }
  public void setHostName(String[] hostName) {
    this.hostName = hostName;
  }
 
  public String getVmemo() {
    return vmemo;
  }
 
  public void setVmemo(String vmemo) {
    this.vmemo = vmemo;
  }
 
  public String getApplyMAC() {
    return applyMAC;
  }
 
  public void setApplyMAC(String applyMAC) {
    this.applyMAC = applyMAC;
  }
 
  public String getApplyIP() {
    return applyIP;
  }
 
  public void setApplyIP(String applyIP) {
    this.applyIP = applyIP;
  }
}

补充知识:vue elementui 页面预览导入excel表格数据

html代码:

<el-card class="box-card">
<div slot="header" class="clearfix">
<span>数据预览</span>
</div>
<div class="text item">
<el-table :data="tableData" border highlight-current-row style="width: 100%;">
<el-table-column :label="tableTitle" >
<el-table-column min-width="150" v-for='item tableHeader' :prop="item" :label="item" :key='item'>
</el-table-column>
</el-table-column>
</el-table>
</div>
</el-card>

js代码:

import XLSX from 'xlsx'
 
data() {
  return {
    tableData: '', 
    tableHeader: '' 
  }
},
mounted: {
  document.getElementsByClassName('el-upload__input')[0].setAttribute('accept', '.xlsx, .xls')
  document.getElementsByClassName('el-upload__input')[0].onchange = (e) => {
    const files = e.target.filesconst itemFile = files[0] // only use files[0]if (!itemFile) 
    return this.readerData(itemFile)
  }
},
methods: {
  generateDate({ tableTitle, header, results }) {
    this.tableTitle = tableTitle
    this.tableData = results
    this.tableHeader = header
  },
  handleDrop(e) {
    e.stopPropagation()
    e.preventDefault()
    const files = e.dataTransfer.files
    if (files.length !== 1) {
      this.$message.error('Only support uploading one file!')
      return
    }
    const itemFile = files[0] // only use files[0]
    this.readerData(itemFile)
    e.stopPropagation()
    e.preventDefault()
  },
  handleDragover(e) {
    e.stopPropagation()
    e.preventDefault()
    e.dataTransfer.dropEffect = 'copy'
  },
  readerData(itemFile) {
    if (itemFile.name.split('.')[1] != 'xls' && itemFile.name.split('.')[1] != 'xlsx') {
      this.$message({message: '上传文件格式错误,请上传xls、xlsx文件!',type: 'warning'});
     } else {
      const reader = new FileReader()
      reader.onload = e => {
        const data = e.target.result
        const fixedData = this.fixdata(data)
        const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
        const firstSheetName = workbook.SheetNames[0] // 第一张表 sheet1
        const worksheet = workbook.Sheets[firstSheetName] // 读取sheet1表中的数据       delete worksheet['!merges']let A_l = worksheet['!ref'].split(':')[1] //当excel存在标题行时
        worksheet['!ref'] = `A2:${A_l}`
        const tableTitle = firstSheetName
        const header = this.get_header_row(worksheet)
        const results = XLSX.utils.sheet_to_json(worksheet)
        this.generateDate({ tableTitle, header, results })
       }
        reader.readAsArrayBuffer(itemFile)
     }
  },
  fixdata(data) {
    let o = ''
    let l = 0
    const w = 10240
    for (; l < data.byteLength / w; ++l) 
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
    return o
  },
  get_header_row(sheet) {
    const headers = []
    const range = XLSX.utils.decode_range(sheet['!ref'])
    let Cconst R = range.s.r /* start in the first row */
    for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
      var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */
      var hdr = 'UNKNOWN ' + C // <-- replace with your desired defaultif (cell && cell.t) 
      hdr = XLSX.utils.format_cell(cell)
      headers.push(hdr)
    }
    return headers
  }

以上这篇VUE动态生成word的实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript div 弹出可拖动窗口
Feb 26 Javascript
JavaScript中SQL语句的应用实现
May 04 Javascript
javascript 函数参数限制说明
Nov 19 Javascript
向当前style sheet中插入一个新的style实现方法
Apr 01 Javascript
javascript封装 Cookie 应用接口
Aug 07 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 Javascript
详解在Angular项目中添加插件ng-bootstrap
Jul 04 Javascript
详解vue中引入stylus及报错解决方法
Sep 22 Javascript
Vue.js搭建移动端购物车界面
Jun 28 Javascript
jQuery实现定时隐藏对话框的方法分析
Feb 12 jQuery
微信小程序获取当前时间及星期几的实例代码
Sep 20 Javascript
react 项目中引入图片的几种方式
Jun 02 Javascript
Element Dialog对话框的使用示例
Jul 26 #Javascript
在vue中使用防抖函数组件操作
Jul 26 #Javascript
Vue 中使用lodash对事件进行防抖和节流操作
Jul 26 #Javascript
浅谈vue中document.getElementById()拿到的是原值的问题
Jul 26 #Javascript
关于vue 结合原生js 解决echarts resize问题
Jul 26 #Javascript
Element Tooltip 文字提示的使用示例
Jul 26 #Javascript
Element Popover 弹出框的使用示例
Jul 26 #Javascript
You might like
php中截取字符串支持utf-8
2007/01/18 PHP
PHP数字和字符串ID互转函数(类似优酷ID)
2014/06/30 PHP
JavaScript 对象模型 执行模型
2010/10/15 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
JavaScript indexOf方法入门实例(计算指定字符在字符串中首次出现的位置)
2014/10/17 Javascript
使用JS画图之点、线、面
2015/01/12 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
JQuery点击事件回到页面顶部效果的实现代码
2016/05/24 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
简单几步实现返回顶部效果
2016/12/05 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
详谈jQuery unbind 删除绑定事件 / 移除标签方法
2017/03/02 Javascript
jQuery插件HighCharts绘制2D金字塔图效果示例【附demo源码下载】
2017/03/09 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
2018/09/17 Javascript
JS实现的获取银行卡号归属地及银行卡类型操作示例
2019/01/08 Javascript
vue移动端实现手机左右滑动入场动画
2020/06/17 Javascript
你不可不知的Vue.js列表渲染详解
2019/10/01 Javascript
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
python中使用xlrd、xlwt操作excel表格详解
2015/01/29 Python
python检查字符串是否是正确ISBN的方法
2015/07/11 Python
Python wxpython模块响应鼠标拖动事件操作示例
2018/08/23 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
基于Python中的yield表达式介绍
2019/11/19 Python
python实现拼图小游戏
2020/02/22 Python
Python self用法详解
2020/11/28 Python
用Python制作音乐海报
2021/01/26 Python
css3实现顶部社会化分享按钮示例
2014/05/06 HTML / CSS
英国在线自行车店:Merlin Cycles
2018/08/20 全球购物
西班牙最好的在线购买葡萄酒的商店:Vinoseleccion
2019/10/30 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
六查六看自检自查剖析材料
2014/10/14 职场文书
信贷客户经理岗位职责
2015/04/09 职场文书
《追风筝的人》:人心中的成见是座大山,但请不忘初心
2019/11/15 职场文书
教你如何用Python实现人脸识别(含源代码)
2021/06/23 Python