如何解决如何使用python docx在Word中自定义编号样式?
在 Word 文件中添加段落时,我尝试使用 python docx 自定义编号样式。
例如,我不想在段落开头添加 '1. '
,而是要执行 'class #1. '
。
有可能吗?有可以直接使用的功能吗?
解决方法
此示例将参数传递给示例文档:
# generate_roombill_docx.py
import re
from pathlib import Path
from models.earning import RoomBill,c_room_bills_serializer
from models.nezha import get_community_name
from .create_docx_by_sample import docx_replace
from .helper import create_sn,verbose_price
async def gen_docx(roombill: RoomBill,host: str,r2=None,target=None):
# 创建docx文件,返回文件路径target,指定让r2/c2采取二合一打印
community_name = await get_community_name(roombill.community)
room_name = roombill.room_name
host = host.replace("www.esoaru.net","esoaru.net")
img = qrcode_path(host,community_name,roombill.room_slug)
where = Path(__file__).parent
sample = where / "sample_模板2.docx"
bills,total = await c_room_bills_serializer([roombill])
params = build_params(
bills,room_name,total,roombill.name,roombill.remark,roombill.period,)
img_data = {"img_paycode": img}
if community_name == "xxx":
params["who"] = (
"深圳艺坤家园物业管理有限公司"
"\n"
"服务中心电话: 0755-28281233 (8:30-21:00)"
"\n"
"监控中心电话: 0755-28283118 (7*24小时)"
)
else:
params["who"] = ""
if r2:
# TODO 2.2: 两个单打印在同一张纸
where = Path(__file__).parent
sample = where / "double_sample.docx"
if target is None:
media = Path("media")
name = f"{room_name}_{r2}.docx" if r2 else f"{room_name}.docx"
target = media / community_name / "通知单" / name
target.parent.exists() or target.parent.mkdir(parents=True)
docx_replace(sample,target,params,img_data)
return str(target)
def doc_fmt(detail):
if not detail:
return ""
d = re.sub(r"<[a-z /]+>","",detail)
d = re.sub(r" ?"," ",d)
d = re.sub(r"\s{2,}",d)
return d
def build_params(
bills: dict,unit: str,community_name: str,total: str,bill_name: str,remark: str = "",period: str = "",# 计费周期备注
) -> dict:
"""构造出模板需要的参数"""
sn = create_sn()
d = {"room": unit,"community": community_name,"sn": sn}
d["total"] = str(total)
d["verbose"] = total and verbose_price(total) or ""
d["bill_name"] = bill_name
d["period_tip"] = "计费周期备注:" if period else ""
d["period"] = period or ""
d["tip"] = "备注:" if remark else ""
d["remark"] = remark or ""
line_num = 1
for bill_id,bill_data in bills.items():
for charge_item in bill_data["charges"]:
for i in charge_item["items"]:
a,b,c = f"n{line_num}1",f"n{line_num}2",f"n{line_num}3"
d[a],d[b],d[c] = i["title"],i["amount"],i["detail"]
line_num += 1
for i in range(1,10):
for j in range(1,4):
k = f"n{i}{j}"
d.setdefault(k,"")
return d
def qrcode_path(host: str,room_slug: str) -> str:
"""返回二维码图片地址,如果图片不存在就调用qrcode生成它"""
media = "media"
p = Path(media) / "qrcodes" / community_name / f"{room_slug}.jpg"
if not p.exists():
if not p.parent.exists():
p.parent.mkdir(parents=True)
import qrcode
if "wanghai" not in host:
qr_host = "https://www.esoaru.com"
else:
qr_host = host.replace("wanghai","www")
link = f"{qr_host}/dist/bill/{room_slug}/paper"
qrcode.make(link).save(p)
return str(p)
create_docx_by_sample.py
#!/usr/bin/env python
from pathlib import Path
from typing import Optional,Union
from docx import Document
from docx.shared import Cm
def docx_replace(
sample_path: Union[str,Path],savepath: Union[str,params: dict,images: Optional[dict] = None,) -> None:
"""根据给定模板和参数,构造新的Word文档,并保存在本地"""
document = Document(sample_path)
if images is None:
images = {}
for paragraph in document.paragraphs:
for run in paragraph.runs:
rtext = run.text
for k,v in params.items():
vname = "${%s}" % k
if vname in rtext:
run.text = rtext.replace(vname,v)
for k,v in images.items():
vname = "${%s}" % k
if vname in rtext:
run.clear()
run.add_picture(v,height=Cm(4.75))
for paragraph in document.paragraphs:
ptext = paragraph.text
# print(ptext)
for k,v in params.items():
vname = "${%s}" % k
if vname in ptext:
paragraph.text = ptext.replace(vname,v)
for table in document.tables:
for row in table.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
ptext = paragraph.text
for k,v in params.items():
vname = "${%s}" % k
if vname in ptext:
paragraph.text = ptext.replace(vname,v)
for k,v in images.items():
vname = "${%s}" % k
if vname in ptext:
# print(ptext)
paragraph.clear()
run = paragraph.add_run()
run.add_picture(v,height=Cm(4.0))
document.save(savepath)
def main() -> None:
params = {
"room": "10-005","sn": "5213","n11": "历史账单:","n12": "物业费","n13": "100.00","n21": "","n22": "停车费","n23": "200","n31": "7月账单:","n32": "物业费","n33": "100.00","n41": "","n42": "停车费","n43": "200","n51": "8月账单:","n52": "物业费","n53": "100.00","n61": "","n62": "停车费","n63": "200","n71": "","n72": "总计:","n73": "5320.00",}
where = Path(__file__).parent
docx_replace(
where / "sample.docx",where / "cuishoudan_demo.docx",{"img_paycode": str(where / "gyy.jpg")},)
if __name__ == '__main__':
import sys
if 'test' in sys.argv:
main()
sample.docx:https://waketzheng.top/public/docx/sample.docx
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。