django
用python-docx在本地先生成自己想要的文件,注意报错比如level=1没有这样的,需要把模板文件先设置一下标题级别,然后删了。
settings.py一些变化
INSTALLED_APPS = [
'django.contrib.admin', # 内置的后台管理系统
'django.contrib.auth', # 内置的用户认证系统
'django.contrib.contenttypes', # 记录项目中所有model元数据
'django.contrib.sessions', # session会话功能
'django.contrib.messages', # 消息提示功能
'django.contrib.staticfiles', # 查找静态资源路径
'corsheaders', # 跨域设置
'user'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 跨域设置,注意位置!
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 设定文件的访问路径,如:访问http://127.0.0.1:8000/media/就可以获取文件
MEDIA_URL = '/media/'
# 设置文件的存储路径,全部存储在media目录下
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py新增
path('question/download/word', views.DownloadQnaireToWord.as_view()), # 导出为word文档
views.py
class DownloadQnaireToWord(View):
base_file = MEDIA_ROOT + '\\user_survey_template\\template.docx' # 模板文件
document = Document(base_file) # 生成的目标文件
# 添加段落内容(文本内容,字体大小,字体颜色,字体粗细)
def addParaText(self, text, size, color, underline, thickness):
p = self.document.add_paragraph() # 段落
p.paragraph_format.line_spacing = 1.5
text = p.add_run(text)
# 判断字体是否加粗(1为不加粗)
if thickness == 1:
text.bold = False
else:
text.bold = True # 加粗
text.font.name = 'Times New Roman'
text.font.size = Pt(size)
text.font.color.rgb = color
text.font.underline = underline
# 添加标题
def addHeadText(self, text, size):
self.document._body.clear_content() # 清空前面的内容
title_ = self.document.add_heading(level=5)
title_.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 标题居中
title_run = title_.add_run(text) # 添加标题内容
title_run.font.size = Pt(size) # 设置标题字体大小
title_run.font.color.rgb = RGBColor(0, 0, 0) # 字体颜色
# 删除非模板文件
def delete_docx_file(self):
filepath = MEDIA_ROOT + '\\user_surveys\\'
if os.path.exists(filepath):
files = os.listdir(filepath)
for file in files:
if file != "template.docx":
os.remove(os.path.join(filepath, file))
# 流方式读取文件
def read_file(self, file_name, size):
with open(file_name, mode='rb') as fp:
while True:
c = fp.read(size)
if c:
yield c
else:
break
def post(self, request):
self.delete_docx_file() # 收到请求后先把上次请求导出时本地生成的docx文件删除
# 文件处理开始,这里有简略
self.addHeadText(x,x) # 文档名
self.addParaText('', 11, RGBColor(0, 0, 0), False, 1) #文件段落
filepath = MEDIA_ROOT + '\\user_surveys\\' # 自己的路径
filename = str(survey.sID) + '-' + survey.sName + '.docx' #自己定义的文件名
self.document.save(filepath + filename) #保存到本地,至此本地文件夹能看到生成的文件
# 文件处理结束,返回文件流
response = StreamingHttpResponse(self.read_file(os.path.join(filepath, filename), 512))
response[
'Content-Type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(filename))
if response:
return response
else:
return JsonResponse({'success': False, 'message': '导出失败,请联系管理员解决!'},json_dumps_params={'ensure_ascii': False})
后端postman测试文件下载无误
post请求时选择send and download,会弹出文件资源管理器,注意把后缀加上,默认只有respoonse的
vue
下载的按钮
<el-button
type="success"
icon="el-icon-upload2"
circle
@click="handleOutWord(item)"
></el-button>
关联的函数
async handleOutWord(item) {
var id = item.sID;
var sName = item.sName;
await new Promise((resolve) => {
this.$http
.post("/question/download/word", JSON.stringify({ sID: id }), {
responseType: "blob",
}) // 乱码一定要加 responseType: "blob"
.then((res) => {
console.log(res,'看一下res是啥');
const data = res.data;
const url = window.URL.createObjectURL(
new Blob([data], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
})
);
console.log(url,'看一下url是啥')
const a = document.createElement("a");
document.body.appendChild(a);
a.style.display = "none";
a.href = url;
let filename=sName;
a.download = filename;
console.log(filename)
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
});
resolve();
});
},
main.js中关于axios的一些设置
部署后
项目部署在阿里云服务器上时,起初提示500(Internet Server Error)原因是目录或者文件的权限没有开启,不能创建、编辑或者删除文件。用chmod 777 文件名或文件夹名
开启即可。