Python批量生成药店顶岗实习总结:模板渲染与docx转doc校验

发布时间:2026/9/18 13:11:54
Python批量生成药店顶岗实习总结:模板渲染与docx转doc校验 简介面向医药类、药学及药品经营与管理等专业顶岗实习学生的药店实习总结文档共收录三篇完整范文可服务于实习报告撰写、周记整理、答辩材料准备与岗前认知梳理。压缩包内仅 1 个 doc 文件约 22KB篇幅紧凑便于查阅和二次编辑。内容以药店营业员、收银员、保管员、值班经理等岗位为主线逐步展开实习目的、时间与单位、地点岗位、工作内容与过程、体会收获及总结反思涉及药品分类陈列、常用药通用名与商品名、功能主治与禁忌、议价沟通、收银开单、调货养护等环节。文中还记录了无处方销售处方药、过期药品清理、顾客品牌信任与健康咨询需求等真实问题并提供问题分析与职业素养思考。已有 62 人学习下载适合需要快速搭建实习总结框架、参考真实案例与表达思路的学生使用。1. 一个文档名背后的批量生成场景《药店顶岗实习总结【三篇】.doc》这类文件名有个共同特征方括号里写着份数扩展名是老的 .doc。它一般出现在学院教务的收件目录、连锁药房人事的交付包、或者培训机构的材料盘里——一份模板套出三份内容不同、版式一致的实习材料交完还要能改成【五篇】【十篇】。手工复制三遍、改人名和门店地址看着快等到要统一调整落款格式或者页边距的时候就知道代价了。这篇文章面向的是想把这类文档做成流水线的人用 python-docx 与 docxtpl 拆结构用模板加变量池生成三份不一样的正文用 LibreOffice 批量转回 .doc最后加一道自动校验确认三篇之间没有整段复制粘贴的痕迹。不需要懂药学需要会写一点脚本、愿意把手上的重复交付变成可重跑的命令。2. 拆解药店顶岗实习总结文档结构、占位符与版式参数2.1 .doc 和 .docx 不是一回事先选处理路径.doc 是 OLE 复合二进制格式本质是一段结构化的二进制流python-docx 读不了.docx 是 ZIP 包加一堆 XML才是脚本能直接操作的东西。所以拿到药店顶岗实习总结【三篇】.doc的第一步不是写渲染逻辑而是决定在哪里改源头用 .doc 存档就先把内容抽出来重建源头可控就直接用 .docx 当模板。格式本质python-docx 能否直接读写常见处理方式.docOLE 二进制复合文档否soffice 批量转换或 Windows 下用 COM 调 Word.docxZIP OOXML是python-docx / docxtpl.dotxOOXML 模板是docxtpl 直接渲染.pdf版式固定流否转换后只做视觉校验不做内容改选型上有个简单判断交付物必须是 .doc就把 .docx 当中间产物最后一步统一转换交付物接受 .docx就全程不碰 .doc省掉一轮格式损耗。提示不要用文本编辑器强改 .doc 的字节也不要用「另存为 .doc」的方式改扩展名Word 打开时会提示文件损坏。2.2 用 python-docx 先把文档结构打印出来改之前先看清结构。实习总结这类文档结构高度套路化标题、个人信息行、实习单位与岗位、实习目的、实习内容、收获与不足、致谢、落款日期中间可能夹一个带边框的考核表。先把段落序号和样式名打出来后面写模板才知道哪些该保留、哪些该替换。# inspect_docx.py from docx import Document doc Document(templates/药店顶岗实习总结.docx) # 只打印前 30 段的索引、样式名和文本前 40 字 for idx, p in enumerate(doc.paragraphs[:30]): print(idx, |, p.style.name, |, repr(p.text[:40])) # 表格单独遍历考核表通常在 tables[0] for t_i, table in enumerate(doc.tables): print(table, t_i, rows, len(table.rows), cols, len(table.columns)) print(table.rows[0].cells[0].text)逻辑说明paragraphs只返回正文段落页眉页脚、文本框、表格里的文字都不在其中所以考核表要单独走tables。style.name是定位段落角色的关键——Heading 1是小节标题Normal是正文List Paragraph往往是要点行。参数上没什么可调的重点是把这份输出存成基线文本渲染完再打印一次做对比一眼就能看出哪些段落被吃掉或串位。2.3 占位符怎么放才不会被 Word 拆散常见的做法是在 .docx 模板里写{{ name }}这样的 Jinja2 变量再用 docxtpl 渲染。坑在于 Word 会把一段连续文字切成多个 run你输入时改一次格式、开一次拼写检查就可能被切于是{{na和me}}落在两个 run 里模板引擎就匹配不到了。规避方式有三种变量只在纯文本段落里用不要在变量中间加粗或换色一次粘贴进去不要中途改格式渲染前先跑一遍合并 run 的预处理。# merge_runs.py把段落内样式相同的相邻 run 合并避免占位符被切开 from docx import Document def merge_runs(paragraph): if not paragraph.runs: return base paragraph.runs[0] for run in paragraph.runs[1:]: if run.font.bold base.font.bold and run.font.size base.font.size: base.text run.text run.text else: base run doc Document(templates/药店顶岗实习总结.docx) for p in doc.paragraphs: merge_runs(p) doc.save(build/template_merged.docx)逻辑说明合并条件是粗体与字号一致实际项目里还可以加上字体名和颜色。要注意这一步会把原本独立的 run 拼成一个如果原文档依赖 run 级别做局部高亮需要先把高亮段落排除在白名单外常见做法是按style.name过滤只处理Normal段落。2.4 版式参数落到代码里实习材料的版式通常有硬要求A4、上下边距 2.54cm、正文小四宋体、行距 1.5 倍、标题黑体加粗。这些别靠人工在 Word 里点写进代码才能在生成阶段保证三篇完全一致。from docx.shared import Cm, Pt from docx.oxml.ns import qn # 页面与正文默认样式 for section in doc.sections: section.page_width Cm(21.0) section.page_height Cm(29.7) section.top_margin Cm(2.54) section.bottom_margin Cm(2.54) section.left_margin Cm(3.17) section.right_margin Cm(3.17) style doc.styles[Normal] style.font.name Times New Roman # 西文 style.element.rPr.rFonts.set(qn(w:eastAsia), 宋体) # 中文必须单独设 style.font.size Pt(12) # 小四 style.paragraph_format.line_spacing 1.5逻辑说明python-docx 的font.name只管西文中文字体要走w:eastAsia这个 XML 属性这是新手最常踩的一脚——设完发现中文还是默认字体。line_spacing 1.5是倍数行距如果要固定值比如 22 磅改用Pt(22)并确认line_spacing_rule处于固定值模式。3. 三篇药店顶岗实习总结不撞车模板渲染与内容变量池3.1 模板骨架与字段清单三篇要不一样靠的不该是写三份文档而是把差异点全抽成字段。药店实习总结的可变字段就那么几类学生姓名与学号、门店名称与地址、带教老师、实习起止时间、轮岗岗位处方调配、OTC 销售、饮片养护、库存盘点、遇到的具体案例、数据指标接待人次、盘点品规数。把这些列清楚模板里就只剩骨架和语序。字段类型出现位置是否允许重复student_name字符串首段、落款三篇不同store_name字符串首段、内容段三篇不同period字符串首段三篇可相同posts列表2~4 项内容段小标题顺序需打乱cases列表1~2 条内容段三篇必须不同metrics字典收获段可相同但措辞要换3.2 变量池把同义句存成 JSON三篇查重不过多数时候不是骨架撞了是「通过本次实习我深刻认识到……」这种句子三份一模一样。解决办法是给每个固定语义准备 3 到 5 种表达存成 JSON 池渲染时按份数轮换取样。{ opening: [ 在{{ store_name }}为期{{ weeks }}周的顶岗实习中我完成了从学生到岗位角色的过渡。, {{ weeks }}周的药店顶岗经历让我第一次完整接触到门店的日常运转。, 从{{ start_date }}起我在{{ store_name }}跟岗学习覆盖了处方调配到库存管理的完整流程。, 这段在{{ store_name }}的实习让我意识到药店的每一项工作都直接对应着用药安全。 ], gain: [ 对处方审核与用药交代的规范要求有了具体认知。, 在饮片养护和效期管理上积累了可复用的操作方法。, 学会了如何向顾客解释用法用量并处理常见咨询。 ] }逻辑说明池子里的句子按索引轮换取样第 1 篇取 0、3、1第 2 篇取 1、0、3而不是直接random.choice否则两篇抽到同一句的概率并不低三篇样本量小的时候更明显。weeks这类数字字段建议先算好再塞进模板不要在模板里做算术Word 里的表达式解析容易出错。3.3 渲染docxtpl 比手工替换靠谱# render.py from docxtpl import DocxTemplate import json, itertools POOL json.load(open(pool/phrases.json, encodingutf-8)) tpl DocxTemplate(build/template_merged.docx) records json.load(open(data/students.json, encodingutf-8)) for i, rec in enumerate(records): ctx { student_name: rec[name], store_name: rec[store], weeks: rec[weeks], start_date: rec[start], posts: rec[posts], case: rec[case], # 轮换取样第 i 篇往后错位取保证三篇不重复 opening: POOL[opening][i % len(POOL[opening])], gain_a: POOL[gain][i % len(POOL[gain])], gain_b: POOL[gain][(i 2) % len(POOL[gain])], } tpl.render(ctx) tpl.save(fbuild/docx/药店顶岗实习总结_{i1}_{rec[name]}.docx)逻辑说明DocxTemplate对象在循环里复用每次render会覆盖上一次的上下文所以必须紧跟save不能先渲染三次再统一保存——这是个高频错误。输出文件名里带上序号和姓名是为了后面转换 .doc 时能对应回人如果编号规则另有要求比如按学号命名把文件名模板抽成配置项别硬编码在代码里。3.4 段落级重组打乱但不打乱逻辑三篇的岗位顺序也建议错开处方调配在前和库存盘点在前读起来就天然不同。做法是给posts列表做受约束的洗牌保留首项必须是最基础的岗位其余随机。约束洗牌比自由洗牌更接近真实写作习惯人写总结不会把最复杂的饮片养护放在开头。import random def shuffle_posts(posts, seed): rng random.Random(seed) # 固定种子保证可复现 head, tail posts[0], posts[1:] rng.shuffle(tail) return [head] tail # 每篇用不同种子同一份数据重跑结果一致 print(shuffle_posts([处方调配, OTC销售, 饮片养护, 库存盘点], seed101))逻辑说明固定种子是关键交付物要能重跑出同样的结果不然改一个错别字就得重新抽一遍。参数seed可以用学生学号的后三位天然区分不同人。4. 从 docx 批量转回 .doc 与格式固化的坑4.1 转换命令与过滤器名Linux 或 macOS 上装好 LibreOffice用 headless 模式批量转一条命令处理整个目录。要转成老式 .doc必须显式指定过滤器MS Word 97只写--convert-to doc在部分版本上会落到别的实现。# 批量 docx - doc输出到 out/doc soffice --headless --convert-to doc:MS Word 97 \ --outdir out/doc build/docx/*.docx # 同时产出 PDF 用于人工翻阅 soffice --headless --convert-to pdf --outdir out/pdf build/docx/*.docx逻辑说明--headless保证不开界面适合放进脚本或 CI--outdir必须提前存在否则转换静默跳过。soffice拿不到用户配置目录时会报错容器里跑建议加-env:UserInstallationfile:///tmp/lo_profile避免并发时抢占同一个 profile 导致失败。注意转换完成后再单独跑一次 PDF不要指望从 .doc 二次转 PDF版面会因为一次格式降级而不一致。4.2 字体、页码与落款表格的坑从 .docx 转 .doc 时最容易丢的不是文字而是版面细节。表格边框和底纹一般能保住页眉里的下划线和域代码容易变形。落款处的签名与日期如果用制表位对齐转换后可能挤在一起比较稳的做法是放在一个两列无边框表格里左边签名、右边日期靠单元格宽度撑开。页码同理别在正文里手写「第 X 页」要在页脚插域。python-docx 没有直接加页码的 API需要往页脚的段落里追加域代码片段如果三篇页数都只有两三页也可以统一不编页码省掉这一类问题。判断标准很简单交付要求里写了页码就做没写就不做。4.3 批量脚本遍历、重试与日志#!/usr/bin/env bash set -uo pipefail SRCbuild/docx OUTout/doc LOGout/convert.log mkdir -p $OUT out/pdf for f in $SRC/*.docx; do name$(basename $f .docx) if soffice --headless -env:UserInstallationfile:///tmp/lo_profile \ --convert-to doc:MS Word 97 --outdir $OUT $f /dev/null 21; then echo OK $name $LOG else echo FAIL $name $LOG fi done # 产出数量与源文件数量必须一致 echo src$(ls -1 $SRC/*.docx | wc -l) out$(ls -1 $OUT/*.doc | wc -l)逻辑说明set -uo pipefail让脚本在变量未定义时直接报错避免空路径把整个 build 目录传进去。循环里逐个转换而不是一次传所有文件是为了让失败只影响单个文件并且能记下是哪一个。最后一行数量比对是最省事的完整性检查数量对不上就去日志里找 FAIL 行。4.4 排错对照表现象常见原因排查动作输出目录为空脚本还返回成功--outdir目录不存在转换前mkdir -p中文变成方框或默认字体系统缺中文字体装字体后重建 fontconfig 缓存表格宽度在 .doc 里被压扁用了自动适应宽度改成固定列宽厘米段首缩进丢失用空格手动缩进改段落格式first_line_indent并发转换报 profile 冲突多个进程共用配置目录每个进程独立UserInstallation5. 交付前自动校验三篇差异度、字数与版式一致性三篇文档生成完人工翻一遍最少十分钟还容易漏。写个两百行的校验脚本把「不该一样的地方一样了」这件事交给程序判断性价比很高。第一层校验是两两差异度。用difflib对正文做序列比对相似度超过阈值就报警。实习总结这类文体本身句式固定正常情况三篇相似度落在 0.4 到 0.6 之间一旦超过 0.75基本可以判定有整段复制。# check_diversity.py import glob, difflib from docx import Document def body_text(path, min_len15): doc Document(path) # 只取正文段落过滤标题和过短行 return [p.text.strip() for p in doc.paragraphs if len(p.text.strip()) min_len] files sorted(glob.glob(build/docx/*.docx)) texts {f: \n.join(body_text(f)) for f in files} THRESHOLD 0.75 for i in range(len(files)): for j in range(i 1, len(files)): ratio difflib.SequenceMatcher( None, texts[files[i]], texts[files[j]]).ratio() flag ALERT if ratio THRESHOLD else ok print(f{flag} {ratio:.3f} {files[i]} - {files[j]})逻辑说明min_len15过滤掉落款、日期这类短行否则「2024年6月30日」这种完全相同的短句会把整体相似度拉高产生误报。SequenceMatcher对中文按字符比对够用且不需要额外分词依赖如果文档里混了大量英文专业名词换成基于词的比对更准但要先做分词。阈值不要设成 0.6正常写作的同义句比例没那么高卡太死只会天天报警告。第二层校验是版式一致性检查三份文档的页面尺寸、边距、正文字号和行距是否完全一致。这些参数在第 2 章已经写进代码但模板被人工改过一次就可能失守。校验项期望值取值方式页面宽度21.0 cmsection.page_width.cm左右边距3.17 cmsection.left_margin.cm正文字号12 ptdoc.styles[Normal].font.size.pt行距1.5paragraph_format.line_spacing正文段数20 ~ 40len([p for p in ... if p.text])考核表列数4len(doc.tables[0].columns)expected {page_w: 21.0, margin_l: 3.17, font_pt: 12.0} for f in files: doc Document(f) s doc.sections[0] assert abs(s.page_width.cm - expected[page_w]) 0.01, f assert abs(s.left_margin.cm - expected[margin_l]) 0.02, f assert doc.styles[Normal].font.size.pt expected[font_pt], f print(layout ok, f)把这两个脚本串进一条命令转换前跑差异度、转换后跑版式日志里同时留 SRC 与 OUT 的文件数。到这里一份药店顶岗实习总结【三篇】.doc从手工复制变成「改 JSON、跑三条命令、看两行日志」——下次要出十篇改的是数据文件里多几行记录而不是打开 Word 再粘贴七遍。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询