文章目录

  • 一、前端
    • 1.1 上传文件
    • 1.2 数据表格
    • 1.3 加密选项
    • 1.4 加密数据
    • 1.5 下载按钮
  • 二、后端
    • 2.1 、upload 文件上传
    • 2.2 table 数据表格接口
    • 2.3 encryption 数据加密
    • 2.4 download 文件下载
  • 三、前后端交互
  • 四、打包exe文件

本文分享知识:

  1. element 中上传组件 upload 的使用方法
  2. table 表格组件、form 表单组件、tooltip 提示框组件
  3. Python 中 os 模块的使用
  4. flask 接受前端传递的文件
  5. pyinstaller 打包 flask 项目

项目源码地址:https://gitee.com/myrensheng/encryption

加密文件比加密字符串更加复杂。

一、前端

页面的布局如下:

第一行为文件上传区,以及显示上传数据的表格。

第二行为加密的选项,以及加密后的数据表格。

1.1 上传文件

<el-upload class="upload-demo" drag :multiple=false :show-file-list=false:on-success="GetTableDate" action="http://127.0.0.1:5000/upload" multiple><i class="el-icon-upload"></i><div class="el-upload__text">只能上传excel文件;<br>将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip"></div>
</el-upload>

el-upload 文件上传组件

on-success 方法,文件上传完成后,调用 GetTableDate 方法

action=“http://127.0.0.1:5000/upload” 上传的地址

1.2 数据表格

<el-table :data="tableData" max-height="250" border style="width: 100%"><el-table-column type="index" :index="indexMethod"></el-table-column><el-table-column v-for="i in tableCols" :prop="i+''" :label="i+''"></el-table-column>
</el-table>

data:显示的数据

el-table-column type=“index” :index=“indexMethod” 显示表格索引

prop 属性,对应列内容的字段名

label 显示的标题

1.3 加密选项

表单组件

<el-form label-width="80px" :model="ruleForm" :rules="rules" ref="ruleForm"><el-form-item label="" prop=""> </el-form-item>
</el-form>

model 表单数据对象

rules 表单验证规则

加密内容输入框

考虑到各种不可预测的因素,以及完成加密多列的功能。这里将加密列全部用 1,2,3,4… 数字表示。即:1 表示第一列,输入的数字用英文逗号(,)隔开。

<el-form-item label="加密列" prop="encryCols"><el-input v-model="ruleForm.encryCols"></el-input>
</el-form-item>

el-input 输入框组件

v-model 输入的内容赋值给 ruleForm.encryCols

加密算法选择框

加密算法有很多中,用一个下拉框组件搞定

<el-form-item label="加密算法"><el-select v-model="ruleForm.encryModel" placeholder="请选择加密算法"><el-option label="md5_32" value="md5_32"></el-option><el-option label="md5_16" value="md5_16"></el-option><el-option label="sha1" value="sha1"></el-option><el-option label="sha224" value="sha224"></el-option><el-option label="sha256" value="sha256"></el-option><el-option label="sha512" value="sha512"></el-option></el-select>
</el-form-item>

el-select下拉框组件

el-option 下拉框中的选项

v-model=“ruleForm.encryModel” 将 el-option 中的 value 值绑定到ruleForm中的 encryModel 变量中

大小写单选框

加密后的字符串可以是大写也可以是小写

<el-form-item label="大写小写"><el-radio-group v-model="ruleForm.encryStyle"><el-radio label="小写"></el-radio><el-radio label="大写"></el-radio></el-radio-group>
</el-form-item>

el-radio-group 单选框

el-radio 单选框中的选项

提交、重置按钮

为防止后端接口请求过于频繁,当没有上传数据时,不请求数据。

重置按钮作用:清空输入框、回复初始化的选项

<el-form-item><el-button type="primary" v-if="tableData" @click="submitForm('ruleForm')">提交</el-button><el-tooltip class="item" v-else effect="dark" content="未上传Excel文件"placement="top-start"><el-button type="danger">提交</el-button></el-tooltip><el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>

用 v-if 、v-else 判断按钮是否需要调用函数

1.4 加密数据

加密数据表格中只显示输入的加密列,以及加密后的数据。

<el-table :data="md5TableData" max-height="250" border style="width: 100%"><el-table-column type="index" :index="indexMethod"></el-table-column><el-table-column v-for="j in md5TableCols" :prop="j+''" :label="j+''"></el-table-column>
</el-table>

data:显示的数据

el-table-column type=“index” :index=“indexMethod” 显示表格索引

prop 属性,对应列内容的字段名

label 显示的标题

1.5 下载按钮

当没有加密数据时,下载按钮不请求后端接口。

<a v-if="md5TableData" href="http://127.0.0.1:5000/download"><el-button type="primary" style="margin-top: 10px;">下载</el-button>
</a>
<el-tooltip class="item" v-else effect="dark" content="没有加密文件"
placement="top-start"><el-button size="small" type="danger" style="margin-top: 10px;">下载</el-button>
</el-tooltip>

用 v-if 、v-else 判断按钮是否需要调用函数

el-tooltip 提示框组件

二、后端

2.1 、upload 文件上传

上传的文件接口,文件保存到同级目录下。当上传新的文件时,需要提前删除之前上传及加密后的文件。

@app.route("/upload", methods=["POST"])
def upload():# 上传文件到 static/excel 文件夹中# 清空数据文件if os.listdir(excel_path):excel_file = os.path.join(excel_path, os.listdir(excel_path)[0])os.remove(excel_file)# 清空已加密的excel文件if os.listdir(encry_excel_path):encry_excel_file = os.path.join(encry_excel_path, os.listdir(encry_excel_path)[0])os.remove(encry_excel_file)if 'file' not in request.files:return jsonify({"status": 400, "msg": "请上传excel文件!"})# 获取文件file = request.files['file']if file.filename != '' and allowed_file(file.filename):# 文件名不为空并且是excel文件filename = file.filenamefile.save(os.path.join(excel_path, filename))return jsonify({"status": 200, "msg": filename + "保存成功!"})return jsonify({"status": 400, "msg": "请上传excel文件"})

os.path.join() 拼接文件地址

os.remove() 删除文件夹下的文件

flask 中使用 request.files[‘file’] 获取上传的文件

file.save() 保存文件

2.2 table 数据表格接口

该接口用于返回上传的excel文件的数据

import xlrd
import xlwtdef get_table_values(file_path=excel_path):# 默认加密第一个表中的数据if os.listdir(file_path):filename = os.path.join(file_path, os.listdir(file_path)[0])workbook = xlrd.open_workbook(filename=filename)table = workbook.sheets()[0]# 默认返回前5行数据# table_rows = 5 if table.nrows >= 5 else table.nrowstable_rows = table.nrowsif table_rows == 0:return {"status": 400, "msg": "excel中没有数据!"}# 获取数据row_list = []for r in range(table_rows):row_dict = {}for k, v in enumerate(table.row_values(rowx=r)):row_dict[str(k + 1)] = vrow_list.append(row_dict)return {"table_cols": table.ncols, "row_list": row_list, "excel_name": os.listdir(file_path)[0],"sheet_name": workbook.sheet_names()[0]}# 没有excel文件或者上传的不是excel文件return None@app.route("/table", methods=["GET", "POST"])
def table():excel_values = get_table_values()# print(excel_values)if excel_values:return jsonify({"status": 200, "msg": "获取数据成功!", "excel_values": excel_values})else:return jsonify({"status": 400, "msg": "请上传excel文件"})

xlrd.open_workbook() 打开指定的excel文件

workbook.sheets()[0] 表示第一个工作薄

table.nrows 表格的行数

table.row_values() 返回对应行的数据

2.3 encryption 数据加密

用于接受前端传递的加密参数

import hashlib
def encryption_str(string, encry_model="md5_32", encry_style=True):# 加密为 utf-8 编码utf_8_str = str(string).encode("utf8")# 函数字典param_dict = {"md5_32": hashlib.md5(utf_8_str),"md5_16": hashlib.md5(utf_8_str),"sha1": hashlib.sha1(utf_8_str),"sha224": hashlib.sha224(utf_8_str),"sha256": hashlib.sha256(utf_8_str),"sha512": hashlib.sha512(utf_8_str)}encry_result = param_dict[encry_model].hexdigest()if encry_model == 'md5_16':encry_result = encry_result[8:-8]# 返回结果return encry_result if encry_style == "小写" else encry_result.upper()def encryption_clos(encry_cols=None, encry_model=None, encry_style=None):# 当加密的是空字符串是不加密,保留空字符串if not encry_model or not encry_cols or not encry_style:return Noneif os.listdir(excel_path):filename = os.path.join(excel_path, os.listdir(excel_path)[0])workbook = xlrd.open_workbook(filename=filename)table = workbook.sheets()[0]# excel 中没有数据if table.ncols == 0:return "excel 中没有数据!"if max(encry_cols) - 1 > table.ncols:# 输入的加密列不在excel中return str(max(encry_cols)) + "超过excel中最大的列"# 开始加密数据encry_workbook = xlwt.Workbook()work_sheet = encry_workbook.add_sheet("md5加密数据")c = 0for col in encry_cols:r = 0col_values = table.col_values(colx=col - 1)work_sheet.write(r, c, str(col))work_sheet.write(r, c + 1, str(col) + "_" + encry_model + "_" + encry_style)for v in col_values:if v == '':encry_v = velse:encry_v = encryption_str(string=v, encry_model=encry_model, encry_style=encry_style)work_sheet.write(r + 1, c, v)work_sheet.write(r + 1, c + 1, encry_v)r += 1c += 2encry_file = os.path.join(encry_excel_path, '加密数据.xlsx')encry_workbook.save(encry_file)# 返回md5文件的前5行数据encry_table_info = get_table_values(file_path=encry_excel_path)return encry_table_inforeturn "服務器內部錯誤"@app.route("/encryption", methods=["GET", "POST"])
def encryption():r_json = request.jsonencry_content = r_json["encryContent"]# 加密算法encry_model = r_json["encryModel"]# 加密类型(大写、小写)encry_style = r_json["encryStyle"]print(encry_content)if encry_content == "textarea":encry_textarea = str(r_json["input_textarea"])res = {"status": 200,"output_textarea": encryption_str(encry_textarea, encry_model=encry_model, encry_style=encry_style),"msg": "加密成功!"}return jsonify(res)# 需要加密的列encry_cols = r_json["encryCols"]if False in [i.isnumeric() for i in encry_cols.strip().strip(",").split(",")]:return jsonify({"status": 400, "msg": "加密列以英文‘,’隔开!"})# 加密成功,直接返回加密后的数据encry_cols = list(set([int(i) for i in encry_cols.split(",")]))encry_excel_values = encryption_clos(encry_cols, encry_model, encry_style)if isinstance(encry_excel_values, dict):return jsonify({"status": 200, "msg": "加密成功!", "excel_values": encry_excel_values})else:return jsonify({"status": 400, "msg": encry_excel_values})

requests.json 获取前端 post 的请求数据

isinstance() 判断变量的数据类型

2.4 download 文件下载

用于下载加密后的文件

@app.route("/download", methods=["GET", "POST"])
def download():return send_from_directory(encry_excel_path, '加密数据.xlsx')

send_form_directory() 用来发送文件

三、前后端交互

用 axios 库来实现前后端数据交互

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!--导入 axios 获取数据-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<script>new Vue({el: '#app',delimiters:['[{', '}]'],data: function() {return {FiledsCheckboxGroup: ['上海'],// EncryRadioGroup: encryptions[0],tableCols: ["上传数据预览"],tableData: null,md5TableCols: ["加密数据预览"],md5TableData: null,// excel名字excel_name: "Excel文件名",sheet_name: null,// 表单数据ruleForm: {encryCols: '',encryModel: "md5_32",encryStyle: '小写',encryContent:'excel'},// 表单验证rules: {"encryCols": [{required: true,message: '请输入加密列',trigger: 'blur'}]},// 单字符串加密output_textarea:null,textareaEncryForm:{encryModel: "md5_32",encryStyle: '小写',input_textarea:null,encryContent:'textarea'},}},methods: {async GetTableDate(response, file, fileList) {// 获取上传excel的数据并展示const {data: res} = await this.$http.get("http://127.0.0.1:5000/table")if (res.status != 200) {this.$message({showClose: true,message: res.msg,center: true,type: 'error'})this.tableCols = ["数据预览,暂无数据"]this.tableData = []} else {this.$message({showClose: true,message: res.msg,center: true,type: 'success'})this.tableCols = res.excel_values.table_colsthis.tableData = res.excel_values.row_listthis.excel_name = res.excel_values.excel_namethis.sheet_name = res.excel_values.sheet_name}},submitForm(formName) {this.$refs[formName].validate(async (valid) => {if (valid) {// 提交需要加密的列const {data: res} = await this.$http.post("http://127.0.0.1:5000/encryption", this.ruleForm)if (res.status == 200) {this.$message({showClose: true,message: res.msg,center: true,type: 'success'});this.md5TableCols = res.excel_values.table_cols;this.md5TableData = res.excel_values.row_list;} else {this.$message({showClose: true,message: res.msg,center: true,type: 'error'})}} else {this.$message({showClose: true,message: "请输入需要加密的列!",center: true,type: 'error'})return false;}});},resetForm(formName) {this.ruleForm.encryModel = "md5_32";this.ruleForm.encryCols = "";this.ruleForm.encryStyle = "小写";this.$refs[formName].resetFields();},indexMethod(index) {return index;},async textareasubmitForm(textareaEncryForm) {const {data: res} = await this.$http.post("http://127.0.0.1:5000/encryption", this.textareaEncryForm)if (res.status == 200) {this.$message({showClose: true,message: res.msg,center: true,type: 'success'});console.log(res);this.output_textarea = res.output_textarea;} else {this.$message({showClose: true,message: res.msg,center: true,type: 'error'})}},textarearesetForm() {this.textareaEncryForm.encryModel = "md5_32";this.textareaEncryForm.input_textarea = null;this.textareaEncryForm.encryStyle = "小写";this.output_textarea = null;},},})
</script>

四、打包exe文件

终于,小凡完成了加密excel文件的事情,考虑到经理和其他需要使用的同事没有Python环境,于是,小凡用 Python中的 pyinstaller 工具,将代码打包为 exe 文件。

pyinstaller -F --add-data="./static;./static" --add-data="./templates;./templates" --add-data="./tools.py;." app.py

flask、element、vue项目实战:搭建一个加密excel数据的网站相关推荐

  1. Vue项目实战——实现一个任务清单(学以致用,两小时带你巩固和强化Vue知识点)

    Vue2.x 项目实战(一) 内容 参考链接 Vue2.x全家桶 Vue2.x 全家桶参考链接 Vue2.x项目(一) Vue2.x 实现一个任务清单 Vue2.x项目(二) Vue2.x 实现Git ...

  2. Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】

    Vue3.x 项目实战(一) 内容 参考链接 Vue2.x全家桶 Vue2.x 全家桶参考链接 Vue2.x项目(一) Vue2.x 实现一个任务清单 Vue2.x项目(二) Vue2.x 实现Git ...

  3. vue 将字符串最后一个字符给替换_前端开发:Vue项目实战-Music

    大家好,我来了,本期为大家带来的前端开发知识是"前端开发:Vue项目实战-Music",有兴趣做前端的朋友,和我一起来看看吧! 主要内容 项目环境搭建 路由导航实现 ListVie ...

  4. 【VUE项目实战】37、商品分类功能介绍和基本结构搭建

    接上篇<36.用户分配角色功能> 上一篇我们完成了为用户分配角色的功能,结束了权限管理模块.本篇我们开启新模块"分类管理"的开发,先进行模块的介绍和基本结构的搭建. 一 ...

  5. vue 动态添加class_前端开发:Vue项目实战-Music

    大家好,我来了,本期为大家带来的前端开发知识是"前端开发:Vue项目实战-Music",有兴趣做前端的朋友,和我一起来看看吧! 主要内容 项目环境搭建 路由导航实现 ListVie ...

  6. Vue项目实战 —— 哔哩哔哩移动端开发—— 第一篇

    目录 前言完 效果图 : 登录含签权 注册带正则 个人中心 下拉加载更多主页 修改个人中心 视频播放加关注+收藏 评论盖楼A回复B B回复C C回复A类似 项目开始 封装登录.注册 封装登录 从零到一 ...

  7. vue项目实战之Layout

    前言 接上篇  基于vue.element的项目实战 ,这一章节将向大家讲解一个项目中的主结构layout,也就是一个项目的导航栏和菜单栏. 一.创建登录页面 在 src 文件夹下创建 page 文件 ...

  8. 【VUE项目实战】59、订单的物流信息查询功能

    接上篇<58.订单修改收货地址的功能> 上一篇我们完成了订单列表的修改收货地址功能,本篇我们来实现订单的物流信息查询功能. 一.要实现的效果 我们要实现点击操作列的"物流进度&q ...

  9. 【VUE项目实战】54、商品添加功能(四)-商品图片上传模块

    接上篇<53.商品添加功能(三)-商品参数及属性模块> 上一篇我们完成了商品参数和商品属性面板的开发,本篇我们来完成商品图片上传模块的开发. 一.要实现的效果 我们在商品图片页签,需要放置 ...

最新文章

  1. 使用OKR管理好团队这四个高深的技巧要明白
  2. 天天向上 专访Data Domain创始人李凯
  3. Windows服务器SYSTEM权限Webshell无法添加3389账户情况突破总结
  4. 5款非常好用的前端在线编辑器推荐
  5. iptables复习记忆
  6. vue js table colspan rowspan
  7. wince的调试串口作为普通串口使用
  8. 一文讲述数仓组件SysCache
  9. 工具---genymotion
  10. python中type(12.34)_下面代码的输出结果是
  11. 学习 WebService 第三步:一个简单的实例(SoapUI测试REST项目)
  12. horizon服务主要模块_得助智能:智能外呼机器人有哪些模块功能层级?
  13. M6(面试)-01-牛客网Java面试题集锦
  14. JAVA 使用SSH/springboot集成 CXF框架发布Webservice
  15. php 跑马灯抽奖,九宫格抽奖跑马灯效果实现--微信小程序
  16. 中国通胀真相:美国向全球转嫁经济调整成本
  17. Java Files.walk示例
  18. Maya_to_Unity工作流程
  19. 为什么实体类要实现serializable接口序列化
  20. 业务:pdf转图片问题(解决非标准pdf转图片空白问题)

热门文章

  1. 宇视免费手机客户端名称是什么
  2. go 语言 proxy.golang.org timeout 超时解决
  3. STM32F103系统时钟设置
  4. 运动控制的轴到底是什么
  5. 数据库入门(sql新建、修改、删除表和基本查询语句)
  6. thinkpad t400,t500 bios设置需要断电后才会生效
  7. 声艺fx16调音台怎么样_声艺(Soundcraft) FX16Ⅱ(RW5757)16路/2立体声 专业调音台
  8. Vue 调用PC摄像头拍照
  9. android 自定义标签导航栏,自定义导航栏app下载-自定义导航栏(Custom Navigation Bar) 安卓版v0.4.3-PC6安卓网...
  10. python操作ffmpeg来合成视频