flask、element、vue项目实战:搭建一个加密excel数据的网站
文章目录
本文分享知识:
- element 中上传组件 upload 的使用方法
- table 表格组件、form 表单组件、tooltip 提示框组件
- Python 中 os 模块的使用
- flask 接受前端传递的文件
- 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.filename
file.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 xlwt
def 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.nrows
table_rows = table.nrows
if 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)] = v
row_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 None
if 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 = 0
for col in encry_cols:
r = 0
col_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 = v
else:
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 += 1
c += 2
encry_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_info
return "服務器內部錯誤"
@app.route("/encryption", methods=["GET", "POST"])
def encryption():
r_json = request.json
encry_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_cols
this.tableData = res.excel_values.row_list
this.excel_name = res.excel_values.excel_name
this.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数据的网站的更多相关文章
- webpack+vue项目实战(四,前端与后端的数据交互和前端展示数据)
地址:https://segmentfault.com/a/1190000010063757 1.前言 今天要做的,就是在上一篇文章的基础上,进行功能页面的开发.简单点说呢,就是与后端的数据交互和怎么 ...
- vue项目实战
本篇文章主要介绍了vue的环境配置,vue项目的目录结构以及在开发vue项目中问题的一些解决方案. 环境配置及目录结构 1.安装node.js(http://www.runoob.com/nodejs ...
- vue项目实战, webpack 配置流程记录
vue项目实战记录,地址在这 购物车单界面 npm install npm run dev 跑起来可以看到界面效果 这里简单记录一下webpack的编译流程 入口 package.json " ...
- vue项目环境搭建与组件介绍
Vue项目环境搭建 """ node ~~ python:node是用c++编写用来运行js代码的 npm(cnpm) ~~ pip:npm是一个终端应用商城,可以换国内 ...
- Vue 项目环境搭建
Vue项目环境搭建 ''' 1) 安装node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ 2) 换源安装cnpm >: npm install -g cnp ...
- 在vue项目中添加一个html页面,开启本地服务器
在vue项目里新增一个不需要登录的页面,那么我只能新增一个html页面了,不经过路由,直接在浏览器输入路径打开,那么就需要用到本地服务器, 1.vue里面的html页面最好放过在public文件夹里面 ...
- 【Rsync项目实战】备份全网服务器数据
[Rsync项目实战]备份全网服务器数据 标签(空格分隔): Linux服务搭建-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转载,转 ...
- 【NFS项目实战二】NFS共享数据的时时同步推送备份
[NFS项目实战二]NFS共享数据的时时同步推送备份 标签(空格分隔): Linux服务搭建-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品, ...
- 如何使用XAMPP本地搭建一个属于你自己的网站
你好,从今天开始,我将为大家带来一些我学习SEO和建站的免费教程,今天为大家带来的是如何用XAMPP搭建一个属于你自己的网站.来到这里,可以说很多在百度上已经过时了的资料需要总结的资料这里都有,你只要 ...
- 推荐一个在线json数据格式化网站
json数据非常友好方便的处理: 推荐一个在线json数据格式化网站 http://json.parser.online.fr/
随机推荐
- [iOS] 随手记录 IDFA 的一些相关内容
IDFA IDFA,广告标识符,类似于这一台设备的唯一性标识符,一般提供给第三方去做一些广告的关联. 但如果用户完全 重置系统,或者 "还原位置与隐私" 这个广告标示符会重新生成 ...
- OS复盘
OS复盘 OS课设已经结课一段时间了,我也从其他课程中抽身出来,有了一段能够好好反思的时光. 说实话,完成OS课设的过程是很痛苦的,指导书蜻蜓点水.注释模棱两可.各种函数和文件调用杂乱无章.每次在完成 ...
- OS-lab1
OS-lab1 boot boot文件夹中只有start.S文件,这个文件用于初始化内核.关掉中断,设置内核栈,并跳转到main函数. init init.c 执行初始化操作. main.c 主函数, ...
- .NET Core基础:白话管道中间件
在Asp.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景 ...
- 插入排序C语言
1 #include "stdio.h" 2 #include "stdlib.h" 3 typedef int ElemType; 4 //直接插入排序 5 ...
- CentOS7 设置防火墙、开放指定端口操作
1, 查看防火墙状态: firewall-cmd --state systemctl status firewalld.service 2, 开启防火墙: systemctl start firewa ...
- 文本超出换行添加white-space:wrap无效
场景描述: 在vue项目中,在Modal弹窗里面使用Form表单组件,然后在FormItem里面放一个div标签用来装文字内容.有时会出现内容超出Form表单宽度但是不换行的问题. 解决方法: 给di ...
- 关于ecplipse中的中文都成乱码的问题
这个问题之前也搞死我了,差不多搞了两个下午才搞好 唉,说多了都是泪 时间过的有点久,不是很记得了,不过我这个问题是装fx包之前发生的,后来我是改了jdk版本的所以可能会有些不同 首先,中文会变成乱码主 ...
- idea插件Tranlation配置有道搜索引擎
idea配置有道翻译引擎 一.更换翻译引擎原因 由于Google在2022年9月末宣布关闭GoogleTranslate在中国的服务,原本在chrome浏览器和idea上使用的google翻译引擎也不 ...
- restful的10个规范、序列化和反序列化的名词解释
# 概念 REST全称是Representational State Transfer,中文意思是表述:表征性状态转移. RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应 ...