python-docx 导出Word写进内存中封装为response

因为公司需要将数据导出为word文件,恰好又是前后端分离开发,所以前端的请求需要携带Token。并不能简单的window.open() 。以及在后端处理Wold的时候用到python-docx模块写起来不是很顺手,就随便封装了一下,然后就是在return这个请求的时候将document对象转化为文件流返回等等吧。

代码如下
# -*- coding:utf-8 -*-
# 项目周报导出模块
# created by xiaofan
from io import BytesIO
from django.http import HttpResponse
from django.utils.http import urlquote
from docx import Document
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_COLOR_INDEX
from docx.shared import Pt, Cm, RGBColor  # 磅数
from docx.oxml.ns import qn  # 中文格式class CreateTable:"""table 操作"""def __init__(self, rows, cols, width_list, height, document, font_size=10, font_color=(0, 0, 0), floats='LEFT',font_name=u'仿宋'):"""添加rows行cols列表格:param rows: 行:param cols: 列:param font_size: 字体大小:param font_color: 字体颜色:param floats: 居中格式"""self.rows = rowsself.cols = colsself.font_name = font_nameself.width_list = width_listself.height = heightself.table = document.add_table(rows=rows, cols=cols, style='Table Grid')self.table.style.font.size = Pt(font_size)self.table.style.font.name = font_nameself.table.style.element.rPr.rFonts.set(qn('w:eastAsia'), font_name)self.table.style.font.color.rgb = RGBColor(*font_color)self.table.style.paragraph_format.alignment = getattr(WD_PARAGRAPH_ALIGNMENT, floats)self.table.alignment = WD_TABLE_ALIGNMENT.CENTERself.set_row_width()def set_row_width(self):for i in range(self.cols):self.table.cell(0, i).width = Cm(self.width_list[i])for i in range(self.rows):self.table.rows[i].height = Cm(self.height)def merge(self, tuple1, tuple2, text, font_name=u'仿宋', font_size=10, bold=False):self.table.cell(*tuple1).merge(self.table.cell(*tuple2))tr = self.table.cell(*tuple1).paragraphs[0].add_run(text)tr.font.name = font_nametr.font.size = Pt(font_size)tr.font.bold = boldxu = self.table.cell(*tuple1)xu.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTERxu.alignment = WD_TABLE_ALIGNMENTxt, y = tuple1self.table.rows[xt].height = Cm(self.height)def write_row(self, tuple1, tuple2, data_list, font_size=11, bold=False):LA, LB = tuple1RA, RB = tuple2if (LA == RA and RB >= LB) or (LB == RB and RA >= LA):if LA == RA:for index, i in enumerate(range(LB, RB)):self._write((LA, i), data_list[index], font_size, bold)returnif LB == RB:for index, i in enumerate(range(LA, RA)):self._write((i, LB), data_list[index], font_size, bold)returndef __add_row(self):return self.table.add_row().cellsdef add_row(self, data_list, color=None, font_size=11, bold=False):""":param bold::param font_size::param data_list: 数据列表:param color: 字体下标和颜色组成的字典 ps: {0:'RED',2:'YELLOW}:return:"""row_cells = self.__add_row()for i in range(self.cols):xa = row_cells[i]xa.width = Cm(self.width_list[i])xa.height = Cm(self.height)xa.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTERxx = xa.paragraphs[0].add_run(str(data_list[i]))xx.font.name = self.font_namexx.font.size = Pt(font_size)xx.font.bold = boldif color and i in color.keys():xx.font.highlight_color = getattr(WD_COLOR_INDEX, color[i])def _write(self, tuple1, text, font_size, bold):xu = self.table.cell(*tuple1)xu.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTERxx = xu.paragraphs[0].add_run(text)xx.font.name = self.font_namexx.font.size = Pt(font_size)xx.font.bold = bold#  周报导出主方法
def weekreport_download():def _write(xp, info, font_type, font_size, bold, underline):xs = xp.add_run(info)xs.font.name = font_type  # 设置西文字体xs.element.rPr.rFonts.set(qn('w:eastAsia'), font_type)  # 设置段中文字体xs.font.size = Pt(font_size)xs.font.bold = boldxs.underline = underlinedef continue_P(xp, infos='', font_type=u'仿宋', font_size=15.0, bold=False, underline=False, undLs=None,defaultundL=(1,)):if not undLs:_write(xp, infos, font_type, font_size, bold, underline)else:for index, ev in enumerate(undLs):if index in [*defaultundL]:_write(xp, ev, font_type, font_size, bold, True)else:_write(xp, ev, font_type, font_size, bold, False)return xpdef add_P(floats='LEFT', infos='', font_type=u'仿宋', font_size=15.0, bold=False, underline=False, jump=0, undLs=None,defaultundL=(1,)):""":param floats:  对齐方式:param infos: 写的内容:param font_type: 字体类型:param font_size: 字体大小:param bold: 是否加粗:param underline: 是否下划线:param jump: 在句尾加几个换行:param undLs: 是否是拼接字符串列表:param defaultundL: 列表中第几个需要加下换线:return:"""xs = document.add_paragraph()  # 初始化建立第一个自然段xs.alignment = eval('WD_PARAGRAPH_ALIGNMENT.' + floats)  # 对齐方式为居中,没有这句默认为左对齐if not undLs:continue_P(xp=xs, infos=infos, font_type=font_type, font_size=font_size, bold=bold, underline=underline)else:for index, ev in enumerate(undLs):if index in [*defaultundL]:continue_P(xp=xs, infos=ev, font_type=font_type, font_size=font_size, bold=bold, underline=True)else:continue_P(xp=xs, infos=ev, font_type=font_type, font_size=font_size, bold=bold)if jump:[document.add_paragraph() for _ in range(jump)]return xsdef add_section(direction=True, first=False):""":param direction:  纸张方向 true为竖版  false横版:param first: 是否是第一节:return:"""if not first:document.add_section()header = document.sections[-1].header  # 获取第一个节的页眉header.is_linked_to_previous = False  # 不继承上一节paragraph = header.paragraphs[0]  # 获取页眉的第一个段落space_num = 47 if direction else 96run = paragraph.add_run('编号: XXXX' + ' ' * space_num + 'XXXXX周报')  # 添加页面内容run.font.size = Pt(10)run.underline = Truesection = document.sections[-1]if direction:section.page_height = Cm(29.7)section.page_width = Cm(21)else:section.page_width = Cm(29.7)section.page_height = Cm(21)document = Document()document.styles['Normal'].font.name = u'仿宋'  # 设置文档的基础字体document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋')  # 设置文档的基础中文字体add_section(first=True)add_P(infos='编号:2021-000', font_size=14, jump=3)# 建立第一个自然段add_P(floats='CENTER', infos='XXXXXX\n项目周报', font_size=36, bold=True, jump=1)add_P(floats='CENTER', infos='(2021.03.08—2021.03.14)', font_size=16, bold=True, jump=11)add_P(floats='CENTER', infos='2021年03月14日', font_size=22, bold=True, jump=1)document.add_page_break()# 建立第二个自然段add_P(floats='CENTER', infos='项目周报', font_size=22, bold=True)add_P(undLs=['  XX', ' XX', ' XX', ' XX', 'XXXX', ' 4.2 ', 'XX', ' XXX ', 'XXXX', ' XXX ','XXX', ' XXXX ', 'XX。'], font_size=12, bold=True, defaultundL=(1, 3, 5, 7, 9, 11))document.add_page_break()#  增加第二节add_section(False)# 插入表格t1 = CreateTable(1, 13, floats='CENTER',width_list=[1.04, 2.64, 1.78, 5.56, 1.86, 1.40, 1.40, 1.40, 1.40, 1.40, 1.40, 0.75, 1.74],height=1.14, document=document)t1.add_row([' ' for _ in range(13)])t1.merge((0, 0), (1, 0), 'XX', bold=True)t1.merge((0, 1), (1, 1), 'XXXXXX', bold=True)t1.merge((0, 2), (1, 2), 'XXXX', bold=True)t1.merge((0, 3), (1, 3), 'XX', bold=True)t1.merge((0, 4), (1, 4), 'XX', bold=True)t1.merge((0, 5), (0, 9), 'XX', bold=True)t1.merge((0, 10), (1, 10), 'XX', bold=True)t1.merge((0, 11), (1, 11), 'XX', bold=True)t1.merge((0, 12), (1, 12), 'XX', bold=True)t1.merge((1, 5), (1, 5), 'XX', bold=False)t1.merge((1, 6), (1, 6), 'XX', bold=False)t1.merge((1, 7), (1, 7), 'XX', bold=False)t1.merge((1, 8), (1, 8), 'XX', bold=False)t1.merge((1, 9), (1, 9), 'XX', bold=False)t1.add_row([1, 'XX', 'XX', 'XX', '6000', '1', '500', '0', '0','XX', '0', 'XX', '0.0%'], color={12: 'RED'})#  这里是将文件保存在内存中bio = BytesIO() document.save(bio)bio.seek(0)response = HttpResponse(bio, content_type='application/msword')response['Access-Control-Expose-Headers'] = 'file_name'response['file_name'] = '周报汇总'response['Content-Disposition'] = 'attachment;filename=%s.doc' % urlquote('周报汇总')return response

python-docx 导出World写进内存中封装为response相关推荐

  1. python生成epub文件_python在内存中生成Zip文件!

    import zipfile import StringIO class MemoryZipFile(object): def __init__(self): #创建内存文件 self._memory ...

  2. html页面提交数据,利用servlet接收数据并写进xml中

    需求如下:  * 需求  * 完成用户注册效果.  具体要求:  1)用户输入信息:用户名,密码,确认密码,性别,出生日期,电子邮箱,地址 .  2)用户输入信息后,调用相关的XML操作类,把数据保存 ...

  3. python抓取html写进excel,python爬虫写入excel

    python爬虫数据怎么排列好后存储到本地excel 爬虫我也是接触了1个月,从python小白到现在破译各种反爬虫机制,我给你说说我的方向: 学习使用解析网页的函数,例如: import urlli ...

  4. python怎么把数据写进txt_python 如何将数据写入本地txt文本文件的实现方法

    一.读写txt文件 1.打开txt文件 file_handle=open('1.txt',mode='w') 上述函数参数有(1.文件名,mode模式) mode模式有以下几种: #w 只能操作写入 ...

  5. 手把手带你用Python完成一个能写进简历的项目(实战篇)

    回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 万战自称不提刃,生来双眼篾群容. 大家好,我是梦魇762459510. 前言 相信大家对任务管理器都不是 ...

  6. python将房贷数据写进excel表格

    说明 使用python以及csv库,生成的贷款等信息写入excel文件. # -*- coding:utf-8 -*- # author: php00py #书香府import time import ...

  7. 深度解析——图片加载到内存中的大小计算内存优化

    本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 最近封装了个高斯模糊组件,正好将图片相关的理论基础也梳理了下,所以,这次就来讲讲,在 Android 中,怎么计算一张图片在 ...

  8. 内存管理:程序是如何被优雅的装载到内存中

    内存作为计算机中一项比较重要的资源,它的主要作用就是解决CPU和磁盘之间速度的鸿沟,但是由于内存条是需要插入到主板上的,因此对于一台计算机来说,由于物理限制,它的内存不可能无限大的.我们知道我们写的代 ...

  9. python实现栈及栈在四则运算中的应用

    定义栈类: class Stack(object) :# 初始化栈为空列表def __init__(self):self.items = []# 判断栈是否为空,返回 True 或 Falsedef ...

最新文章

  1. 【跃迁之路】【425天】刻意练习系列184—SQL(2018.04.06)
  2. iPhone为什么关机后仍可定位?“永远在线”处理器断电时也能启动Find My
  3. java中dateformat类的作用_java-SimpleDateFormat类中可用的日期格式是什么?
  4. 在网页中给Flash加上超级链接
  5. java public 继承_java继承问题
  6. (王道408考研数据结构)第五章树-第四节4:红黑树基本概念及操作
  7. Redis 优势以及性能问题
  8. mysql数据库容灾方案_本地IDC机房数据库容灾解决方案
  9. 尼康 Nikon Capture nx2
  10. 微信小程序·实现列表页和详情页同步收藏
  11. 模拟电子技术之运算放大器
  12. php 识别lrc,自动识别LRC歌词精选.pptx
  13. ONOS(Open Network Operating System) from ONF
  14. MySql打开局域网及广域网端口
  15. 思维模型:建立高品质思维的30种模型
  16. Elasticsearch[2.0] ☞ Java Client API ☞ Percolate API
  17. 电脑大写,电脑大写键盘怎么打开
  18. 海淘thinkpad-t460p攻略
  19. 为什么在Google上搜不到我的网页
  20. 老牛知点所以然-Linux(Ubuntu)配置安卓开发环境及过程中常见问题解决

热门文章

  1. 21-6-27 蛇梯棋
  2. 算法作业——打靶问题
  3. 像素之间的转换 之 px与rem的转换
  4. vue打包页面空白解决方法
  5. PS网页设计教程XVIII——在Photoshop中设计优雅的乡村酒店或餐厅的网页布局
  6. npm安装stylus和stylus-loader
  7. 【Oracle】开窗函数、分组排序 row_number\partition by 详解
  8. 【写论文的注意事项】
  9. Pycharm 添加表头作者日期等
  10. 网易面试题:男女小孩战队问题