diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 00000000..0df453a5 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,33 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries + +name: Upload Python Package + +on: + release: + types: [created] + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.8' # py_pkg 需要大于 3.6 + # 依赖安装换成前面的脚本 + - name: Install dependencies + run: | + python3 -m pip install --upgrade build + python3 -m pip install --user --upgrade twine + # 构建和发布换成前面的脚本 + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USER }} + TWINE_PASSWORD: ${{ secrets.PYPI_PWD }} + run: | + python3 -m build + python3 -m twine upload dist/* diff --git a/.gitignore b/.gitignore index 8d51de05..9614a47c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ + +# demo script/ .idea/ .gitee/ @@ -8,14 +10,5 @@ venv/ build/ dist/ *.egg-info +**/qtpy/** __pycache__ - -# Test files -tests/test_files/ - -# PyInstaller -*.spec -*.manifest -*.exe -*.app -*.dmg diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 3f4e9130..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "python.analysis.typeCheckingMode": "off", - "python.languageServer": "None", - "python.testing.unittestArgs": [ - "-v", - "-s", - "./tests", - "-p", - "test_*.py" - ], - "python.testing.pytestEnabled": false, - "python.testing.unittestEnabled": true -} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e81e830f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM dockerhub.cloud/library/python:3.7 + +# 配置环境变量 +ENV PYTHONUNBUFFERED 1 +#ARG PIP_MIRROR + +# 安装依赖环境 +RUN mkdir /app +COPY requirements.txt /app +# RUN pip install -r /app/requirements.txt -i "${PIP_MIRROR}" +RUN pip install -r /app/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ +# 拷贝项目代码 +COPY . /app +WORKDIR /app/thrillerbark + +RUN chmod +x start.sh + +EXPOSE 8000 + +ENTRYPOINT ["sh", "./start.sh"] + +#https://www.idc1680.com/1090.html diff --git a/ISSUES_AUDIT.md b/ISSUES_AUDIT.md deleted file mode 100644 index 55237c09..00000000 --- a/ISSUES_AUDIT.md +++ /dev/null @@ -1,256 +0,0 @@ -# python-office 代码审计报告 - -审计方式:多 agent 并行工作流(survey → 4 路并行查找 → 对抗式验证 → 用户视角缺口分析,共 42 个 agent), -对 `office/lib/**`、`office/api/**`、`office/compatibility.py`、`setup.cfg`、`tests/**` 做了逐行验证。 -所有条目均已通过独立的"对抗式验证"agent 复核(默认不信任发现者,要求验证者亲自读代码定位到具体行才能确认), -未通过验证的 6 条已剔除。以下按严重程度排列,每条给出文件、行号、具体触发场景,可直接据此实现修复。 - ---- - -## 已修复(本次会话完成) - -### `office/api/pdf.py` — `add_img_water()` 是完全的空操作(no-op) -- **文件**:`office/api/pdf.py:301-341` -- **问题**:该函数解析完弃用参数别名后,直接结束,**从未调用 `popdf.add_img_water(...)`**。对比同文件里其他所有函数(`pdf2docx`、`merge2pdf`、`del4pdf` 等)都以 `popdf.xxx(...)` 结尾,这个函数是唯一的例外。 -- **后果**:调用 `add_img_water(input_file=..., mark_file=..., output_file=...)` 静默返回 `None`,不生成任何文件,不抛异常,用户完全无法感知失败。 -- **修复**:补上委托调用,注意 `popdf.add_img_water` 的真实签名是旧式参数名 `(pdf_file_in, pdf_file_mark, pdf_file_out)`(已通过 `pip install popdf` 安装后用 `inspect.signature` 验证),不是新参数名: - ```python - popdf.add_img_water(pdf_file_in=input_file, pdf_file_mark=mark_file, pdf_file_out=output_file) - ``` -- **验证**:直接加载模块并调用,确认参数正确传递到 `popdf` 内部(`popdf` 自身另有一个独立 bug——`popdf.lib.pdf.add_watermark_service` 缺失 `pdf_add_watermark`,这是 `popdf` 包自己的问题,与本仓库无关,`popdf/__init__.py` 也已将 `add_img_water` 标记为 `__deprecated__`)。 -- **状态**:已在本地修改,未提交。 - ---- - -## 待修复:高严重度(崩溃 / 挂起 / 常规用法下出错) - -### 1. `office/lib/excel/SplitExcel.py:53` — 使用了未导入的 `tqdm` -```python -for r in tqdm(range(rows)): -``` -文件顶部只 `import os, xlrd, xlwt, openpyxl, datetime`,没有 `import tqdm`。任何调用 `process_xls`(即 `.xls` 文件走 `split_excel_by_column`)都会立刻 `NameError: name 'tqdm' is not defined`,包括文件自己 `__main__` 里的示例调用。 -**修复**:加 `from tqdm import tqdm`。 - -### 2. `office/lib/excel/SplitExcel.py:100` — 使用已被移除的 openpyxl API -```python -worksheet = workbook.get_sheet_by_name(worksheet_name) -``` -`get_sheet_by_name` 在 openpyxl 2.x 就已弃用,3.x 完全移除。只要调用 `split_excel_by_column(..., worksheet_name='Sheet2')`(函数签名明确支持的合法用法),就会 `AttributeError: 'Workbook' object has no attribute 'get_sheet_by_name'`。 -**修复**:改为 `workbook[worksheet_name]`。 - -### 3. `office/lib/image/eliminate_background.py:42-45` — 非 `.jpg`/`.png` 扩展名时 `r,g,b` 未定义 -```python -if src_img_path.endswith('.jpg'): - r, g, b = pix[...] -elif src_img_path.endswith('.png'): - r, g, b, _ = pix[...] -# 无 else 分支 -``` -没有 `bc_color` 且文件名是 `.jpeg`(常见的 JPEG 备用扩展名)或大写 `.JPG` 时(`.endswith` 大小写敏感),两个分支都不走,`r/g/b` 从未赋值,后续第 52-55 行使用时直接 `NameError`。 -**修复**:加 `else` 分支统一处理,或调用前先 `img.convert('RGBA')` 再取像素,不依赖扩展名字符串判断格式。 - -### 4. `office/lib/image/eliminate_background.py:43` — 非 RGB 模式 JPEG 导致解包错误 -```python -r, g, b = pix[int(width / 20), int(height / 20)] -``` -这行在 `img.convert("RGBA")`(第 47 行)**之前**执行,此时如果图片是灰度模式 `'L'`(单通道,合法的 JPEG),`pix[x,y]` 返回单个 int,解包报 `TypeError: cannot unpack non-iterable int object`;CMYK 模式则返回 4 元组报 `ValueError: too many values to unpack`。 -**修复**:取像素前先 `img.convert('RGB')` 规范化模式。 - -### 5. `office/lib/pdf/add_watermark_service.py:3` — import 已移除的 PyPDF2 旧 API,模块直接无法加载 -```python -from PyPDF2 import PdfFileWriter, PdfFileReader, PdfReader, PdfWriter -``` -`PdfFileWriter`/`PdfFileReader` 在 PyPDF2 3.0+ 完全移除;即使代码里只用到 `PdfReader`/`PdfWriter`,Python 的 `from X import a, b, c, d` 是原子操作,任何一个名字不存在就整行失败。**只要装的是现代 PyPDF2,这个模块连 import 都会报 `ImportError`**,导致整个模块(包括写得对的 `pdf_add_watermark`)完全不可用。 -**修复**:删掉未使用的 `PdfFileWriter, PdfFileReader`。 - -### 6. `office/lib/tools/pwd4wifi_service.py:80` 和 `:101` — 库函数里调用 `exit(0)` -```python -if interface.status() == 4: - print(f'连接成功!密码为:{pwd}') - exit(0) -``` -`wifi_password_crack()` 是普通函数,不在 `__main__` guard 内。`exit(0)` 抛 `SystemExit`(继承自 `BaseException`,外层 `except Exception` 捕不到)。如果任何 Web 服务/GUI 程序 import 这个模块并调用它,破解成功的那一刻会直接**杀死整个宿主进程**,而不是把密码返回给调用者。 -**修复**:把两处 `exit(0)` 改成 `return pwd`(并调整函数返回值设计,让调用者能拿到结果)。 - -### 7. `office/lib/tools/pwd4wifi_service.py:52` — 无超时的忙等待循环 -```python -while interface.status() == 4: - pass -``` -纯自旋等待,没有 `sleep`、没有超时。如果网卡状态因为驱动/虚拟环境等原因一直停在 4(已连接),会无限占满一个 CPU 核心且永不返回。 -**修复**:加 `time.sleep(0.1)` 和最大重试次数/超时时间。 - -### 8. `office/lib/tools/pwd4wifi_service.py:64-84` — pwd_list 全部试错后死循环 -```python -while True: - if pwd_list: - for pwd in pwd_list: - ... - print(f'{pwd_list}中,没有合适的密码') - # 没有 break,会再次回到 while True 顶部,重复同样的列表 -``` -提供的密码列表全部尝试失败后,没有 `break`/`return`,会带着同一份列表无限重试,函数永不返回。 -**修复**:for 循环结束后加 `break` 或 `return None`。 - -### 9. `office/lib/tools/weather_service.py:12-13` — 正则匹配失败时下标越界 -```python -weather = pat_weather.findall(content) -print(weather[0]) # 12 -print('更新时间:', up_time[0]) # 13 -``` -目标网页结构变化、URL 错误或被重定向时 `findall` 返回 `[]`,`[0]` 直接 `IndexError`,两处都没有任何保护。爬虫类代码这是最常见的失败模式,不是极端情况。 -**修复**:判空后再取,取不到时给出明确的错误信息而不是裸 `IndexError`。 - -### 10. `office/lib/decorator_utils/instruction_url.py:123` — 装饰器里字典漏配就整个函数报错 -```python -if func_filename in instruction_file_dict.keys() and instruction_file_dict[func_filename][func.__name__]: -``` -新增一个被 `@instruction` 装饰的函数,但忘了在对应的 `xxx_dict` 里加它的 key,调用这个新函数直接 `KeyError`,**函数体根本不会执行**(这行代码在真正调用 `func(*args, **kwargs)` 之前)。 -**修复**:改成 `instruction_file_dict.get(func_filename, {}).get(func.__name__)`。 - -### 11. `office/compatibility.py:36` + 239 — import 期无保护的文件系统写入 -```python -# 第239行,模块级别,import 时无条件执行: -compatibility_checker = check_compatibility() -``` -内部调用链最终会 `mark_file.write_text(...)`,没有任何 try/except。只读 HOME 目录(常见于部分 CI 容器、锁定的企业 Windows 账户)下 `import office` 会直接抛 `PermissionError`/`OSError`,**导致整个包无法导入**,不仅仅是兼容性提示功能失效。 -**修复**:给这段包裹 try/except,写入失败时静默跳过提示,不应该影响正常导入。 - -### 12. `office/api/pdf.py:301`(历史bug,已修复,见上方"已修复"章节) - ---- - -## 待修复:中等严重度(边界情况崩溃 / 静默错误吞掉 / 资源泄漏) - -### 13. `office/lib/excel/SplitExcel.py:42-45, 95-98` — 裸 `except:` 吞掉所有异常 -两处(`.xls` 和 `.xlsx` 分支)都用裸 `except:` 把权限错误、文件损坏、内部解析 bug 全部压成同一句 `"文件读取异常:{filepath}"`,调用者无法区分"文件不存在"和"文件被占用"和"文件损坏"。 -**修复**:改成 `except Exception as e:`,并把 `e` 的信息带进返回消息。 - -### 14. `office/lib/excel/SplitExcel.py:96` — `openpyxl.load_workbook(..., read_only=True)` 从不 `close()` -read_only 模式下 openpyxl 官方文档要求显式 `close()` 释放文件句柄;批量处理很多文件时会逐渐耗尽文件描述符,最终 `OSError: Too many open files`。 -**修复**:用 `with` 或 `try/finally` 确保 `workbook.close()`。 - -### 15. `office/lib/pdf/add_watermark_service.py:47,62` — 输入流从不关闭 -`input_stream`/`mark_stream` 用 `open()` 打开后从未 `close()`,加密文件解密失败时的 `return False`(第58行)更是直接跳过后续所有清理。批量处理场景下会泄漏文件句柄。 -**修复**:用 `with open(...)` 或 `try/finally`。 - -### 16. `office/lib/pdf/add_watermark_service.py:67` — 水印 PDF 页数为 0 时下标越界 -```python -page.merge_page(pdf_watermark.pages[0]) -``` -没有检查水印 PDF 至少有一页,如果调用者传入一个 0 页的水印文件,直接 `IndexError`,没有任何友好提示。 -**修复**:调用前检查 `len(pdf_watermark.pages) > 0`。 - -### 17. `office/lib/image/add_watermark_service.py:41` — `set_opacity()` 假设图片一定有 alpha 通道 -```python -alpha = im.split()[3] -``` -这是一个导出的公共函数,文档没写"必须是 RGBA",直接传 RGB 图片进来会 `IndexError: tuple index out of range`。当前内部唯一调用点碰巧总是传 RGBA,但作为公共 API 缺少防护。 -**修复**:函数开头 `im = im.convert('RGBA')` 或在文档里明确注明前置条件并加断言。 - -### 18. `office/lib/image/add_watermark_service.py:138` — 批量水印失败时静默吞掉所有异常 -```python -except Exception as e: - print(new_name, "保存失败。错误信息:", e) -``` -`add_mark2file` 返回类型标注是 `-> None`,任何失败(字体文件缺失、磁盘满、权限错误)都只是 print,调用者拿到的返回值和成功时完全一样(都是 `None`),批处理脚本无法判断真的成功了没有。 -**修复**:至少改为返回 `bool` 表示成功/失败,或重新抛出异常让调用者决定怎么处理。 - -### 19. `office/lib/ppt/ppt2pdf_service.py:26-31` — PowerPoint COM 对象失败时永不 `Quit()` -```python -ppt = ppt_app.Presentations.Open(filename) -ppt.SaveAs(output_filename, 32) -ppt_app.Quit() # 前面任何一步抛异常,这行就永远不会执行 -``` -没有 try/except/finally。`SaveAs` 因为路径不存在等原因失败时,`ppt_app.Quit()` 被跳过,后台留下一个隐藏的、看不见窗口的 PowerPoint.exe 进程,Python 垃圾回收也不保证真正结束这个进程。批量处理失败文件会累积多个孤儿进程。 -**修复**:整个函数体包 try/finally,finally 里调用 `ppt_app.Quit()`。 - -### 20. `office/lib/tools/pwd4wifi_service.py:14, 48` — 硬编码取第一个无线网卡,无边界检查 -```python -interface = wifi.interfaces()[0] -``` -没有无线网卡(无头服务器、网卡被禁用)时 `wifi.interfaces()` 返回空列表,`[0]` 直接 `IndexError`。 -**修复**:判空后给出"未检测到无线网卡"的明确提示。 - -### 21. `office/lib/image/eliminate_background.py:36` — `_hex_to_rgb` 返回 `None` 时解包崩溃 -```python -r, g, b = _hex_to_rgb(bc_color) -``` -`_hex_to_rgb` 对格式不对的颜色字符串(比如漏了开头的 `#`)只是 print 警告然后 `return None`,这里直接解包 `None` 会报一个和真实原因毫无关系的 `TypeError: cannot unpack non-iterable NoneType object`。 -**修复**:`_hex_to_rgb` 改成抛 `ValueError` 并带上清晰的错误信息,而不是返回 `None` 再让调用方莫名其妙崩溃。 - -### 22. `office/api/finance.py:22` — 返回类型标注与实际返回值不符 -```python -def t0(...) -> float: - ... - return stock_returns # 实际是 Decimal 对象 -``` -函数内部全程用 `Decimal` 计算,标注却是 `float`。调用者如果用 `isinstance(result, float)` 判断或 `json.dumps({'profit': t0(...)})` 序列化,会直接 `TypeError: Object of type Decimal is not JSON serializable`。 -**修复**:函数末尾 `return float(stock_returns)`,或把标注改成 `-> Decimal`(如果希望保留精度,后者更合理,但要同步更新文档)。 - -### 23. `office/__init__.py` — `office/api/web.py` 被遗漏,未在包初始化时导入 -`office/__init__.py` 第 7-19 行导入了 email/excel/file/finance/image/pdf/ppt/tools/video/wechat/word/markdown/ocr,唯独漏了 `web`。`office/api/web.py` 里的 `url2ebook()` 实际存在且 `pospider` 依赖也已在 `setup.cfg` 声明,但 `import office; office.web.url2ebook(...)` 会报 `AttributeError: module 'office' has no attribute 'web'`,跟其他模块的使用方式不一致。 -**修复**:在 `office/__init__.py` 里加一行 `from office.api import web`。 - ---- - -## 待修复:低严重度 / 测试与流程问题 - -### 24. `tests/test_code/test_tools/` 缺少 `__init__.py` -`tests/test_code/test_tools.py`(文件)和 `tests/test_code/test_tools/`(目录)同名,Python 优先解析成模块而不是包,导致目录下的 `test_trans.py` 对 `unittest discover()` 完全不可见(`python -m unittest discover` 静默报 0 个测试,退出码 5)。已用隔离环境实测复现,加上 `__init__.py` 后确认修复。pytest 默认配置不受影响(其收集机制不依赖这个)。 -**修复**:新增 `tests/test_code/test_tools/__init__.py`(空文件即可)。 - -### 25. 测试文件之间工作目录(CWD)约定不一致,没有单一 CWD 能让所有测试都通过 -`test_excel.py`/`test_file.py`/`test_image.py`/`test_ruiming.py` 等用 `'../test_files/...'`(相对 `tests/test_code/`),而 `test_pdf.py` 用 `'./tests/test_files/pdf/...'`(相对仓库根目录)。两种约定互斥:CWD 设为 `tests/test_code/` 时 `test_pdf.py` 失败,CWD 设为仓库根目录时其他测试失败。且仓库里没有 `conftest.py`/`pytest.ini` 统一配置。 -**修复**:统一所有测试文件的路径基准(建议都改成基于 `os.path.dirname(__file__)` 的相对路径,不依赖进程 CWD),或补一个 `conftest.py` 固定 CWD。 - -### 26. `tests/test_code/test_ppt.py:22-25` — 已知会失败的测试没有标记 skip -```python -# todo: 文件打开有异常 -def test_ppt2img(self): - ppt2img(...) -``` -作者已经在注释里承认这个测试有已知异常,但没有用 `@unittest.skip("原因")` 标记,导致每次跑全量测试都会看到一个"预期内"的失败,和真正的新增回归无法区分。 -**修复**:加 `@unittest.skip("文件打开有异常,待修复")` 装饰器,或修复根本问题后去掉注释。 - ---- - -## 用户视角的功能缺口(按 影响 × 实现难度 排序,均可在本仓库单个 PR 内完成,不涉及外部 po* 包) - -### 1. 非 Windows 首次 `import office` 时兼容性提示可能打印两次,且无法关闭 -`office/compatibility.py` 的 `check_compatibility()` 在模块级别(import 时)执行一次,`office/__init__.py` 又显式调用了一次,非 Windows 用户第一次 `import office` 可能看到两遍完整的 rich 表格输出。没有任何环境变量或参数可以关闭它,唯一的"开关"是 `~/.python-office/first_run_mark` 标记文件,且这个文件的写入本身还有前面提到的 bug 11(无保护写入可能直接让 import 失败)。 -**建议修复**:去重两处调用(只保留 `__init__.py` 里的),加一个 `PYTHON_OFFICE_NO_BANNER` 环境变量在 `display_warning()` 开头判断并直接 return。 -**影响**:高——所有非 Windows 新用户的第一印象都会被这段意外的 stdout 输出干扰,在 CI/notebook 场景下更是噪音污染。 -**难度**:低——只涉及 2 个文件。 - -### 2. `except_dec` 装饰器统一吞异常、只 print、从不重新抛出 -`office/lib/utils/except_utils.py` 的 `except_dec` 捕获所有异常,打印一段装饰性文字后返回 `None`,从不 `raise`,也不走 `logging`/`loguru`(`loguru` 已经是 `setup.cfg` 里声明的依赖,但完全没用上)。调用者没法区分"函数本来就该返回 None"和"函数内部出错了"。 -**建议修复**:把 `print()` 换成 `logging.getLogger('office').exception(...)` 或用已声明的 `loguru`,并把原始异常重新抛出(或提供一个可选参数控制是否吞掉)。 -**影响**:高——这是个跨多个模块使用的公共装饰器,行为改一次全局受益,但需要先排查所有调用点确认没有依赖"吞异常返回 None"这个行为。 -**难度**:中高——单文件改动,但要审计所有 `@except_dec` 使用点。 - -### 3. 没有统一的异常体系,调用者无法用一个 `except` 兜住所有 python-office 自己抛出的错误 -`word.py` 的 `_load_poword()` 会抛一个写得很好的自定义 `ModuleNotFoundError`,但没有一个 `office.exceptions.OfficeError` 基类。用户想统一捕获"python-office 抛出的任何错误"时,必须枚举 `ModuleNotFoundError`/`ImportError`/`AttributeError` 等各种底层异常类型。 -**建议修复**:新增 `office/exceptions.py`,定义 `OfficeError(Exception)` 及若干子类(如 `MissingDependencyError(OfficeError)`),让现有的 `_load_poword` 等函数改用子类抛出(因为是继承关系,现有 `except ModuleNotFoundError` 的代码不受影响)。 -**影响**:中高——纯增量修改,向后兼容。 -**难度**:低——新增一个文件加几处 import 改动。 - -### 4. 没有 `py.typed` 标记,IDE 自动补全体验差,与"一行代码"的产品定位矛盾 -`office/` 下没有 `py.typed` 文件。按 PEP 561,没有这个标记的包,类型检查器(mypy/pyright)会把整个包当作无类型对待,即使代码里已经写了一部分类型标注。这个库自我定位是"零基础一行代码搞定办公自动化",恰恰是最依赖 IDE 参数提示的用户群体,却得不到任何补全支持。 -**建议修复**:新增空文件 `office/py.typed`,在 `setup.cfg` 的 `package_data`/`include_package_data` 里注册,同时把 `office/api/*.py` 里已经部分标注类型的函数补全返回类型标注(比如很多写了 `Returns: None` 文档但函数签名没有 `-> None`)。 -**影响**:高——直接影响目标用户群体的核心体验(IDE 自动补全)。 -**难度**:低——加文件 + 打包配置一行 + 机械性补标注,不涉及外部包。 - -### 5. 没有 CLI 入口,与"办公自动化工具"的产品定位不符 -`setup.cfg` 的 `[options]` 里没有 `[options.entry_points]`/`console_scripts` 配置。尽管官网宣传"73个即用型 Skill,一行代码搞定办公自动化",非开发者用户(README 自己列的"使用场景"里包括办公室职员、学生)仍然必须先写一个 `.py` 文件才能跑任何一个转换功能,无法直接在终端/批处理脚本里一条命令调用。 -**建议修复**:新增 `office/cli.py`,用标准库 `argparse`(避免引入新的重依赖)暴露最高频的几个 skill 作为子命令(如 `pdf2docx`、`docx2pdf`、图片压缩等),在 `setup.cfg` 新增 `[options.entry_points]` 注册 `office = office.cli:main`。 -**影响**:中——显著降低非开发者用户的上手门槛,但属于增量能力,不修复现有断裂的工作流。 -**难度**:中——需要决定覆盖哪些 skill(避免一次性想覆盖全部 73 个导致范围失控),建议先选 5-10 个高频功能,单个 PR 内可完成。 - ---- - -## 附:验证方法说明 - -- 每条"已确认"的问题都经过独立的对抗式验证 agent 复核:验证者被要求默认不信任发现者的结论,必须自己读取对应文件的确切行号,找到问题代码原文引用后才能给出 `confirmed: true`。 -- 有 6 条最初被发现者提出、但未通过对抗式验证的候选问题已被剔除,不在本文档中(多为对 `setup.cfg` 平台标记的误报,验证后确认标记是正确的)。 -- 涉及外部 PyPI 包(`poexcel`/`poword`/`popdf`/`poimage` 等,均不在本仓库内)内部的 bug 不在本次审计范围内,除非该 bug 是本仓库 wrapper 层代码直接导致的(如条目 1 的 `add_img_water`,问题出在 wrapper 层缺失调用,而不是 `popdf` 内部逻辑)。 diff --git a/PR-154-review.md b/PR-154-review.md deleted file mode 100644 index 73c7bfa0..00000000 --- a/PR-154-review.md +++ /dev/null @@ -1,113 +0,0 @@ -# PR #154 代码审查报告 — feat(word): 支持隐藏 doc2docx 转换进度条 - -> 审查方式:基于 PR diff 静态分析 + 本地仓库 `develop` 分支(HEAD `c8f263d`)交叉核对 -> 注:`gh` CLI 未登录 GitHub,本报告未发布为 PR 评论。如需发布,请先 `gh auth login`。 - -## 一、PR 元数据 - -| 项 | 内容 | -|----|------| -| **标题** | feat(word): 支持隐藏 doc2docx 转换进度条 | -| **作者** | [@forever-ivy](https://github.com/forever-ivy) | -| **源分支** | `forever-ivy:feat/doc2docx-progress-toggle` | -| **目标分支** | `CoderWanFeng:develop` | -| **变更文件** | 3 个(`office/api/word.py`、`skills/word/doc2docx/SKILL.md`、`tests/test_code/test_word_api_parameters.py`) | -| **提交数** | 1(67 additions, 3 deletions) | -| **修复 Issue** | #139 | -| **底层依赖** | `CoderWanFeng/poword#3`(**当前状态:OPEN,未合并**) | - -## 二、提交列表 - -- `feat(word): 支持隐藏 doc2docx 转换进度条`(1 commit) - -## 三、变更概览 - -| 文件 | 类型 | 关键改动 | -|------|------|----------| -| `office/api/word.py` | 修改 | `doc2docx` 新增 `show_progress: bool = True`;`show_progress=False` 时向 `poword.doc2docx` 转发 `show_progress=False`,否则不传该键保持兼容 | -| `skills/word/doc2docx/SKILL.md` | 修改 | 示例与参数表补充 `show_progress` | -| `tests/test_code/test_word_api_parameters.py` | 新增 | mock `poword`,验证默认调用与显式隐藏两种参数转发 | - -## 四、自动化发现 - -### 🟠 BLOCKER — PR 基于过时 develop,合入将冲突并覆盖 #157 的改进 -**文件**:`office/api/word.py`(`doc2docx`) - -本地 `develop` 当前 HEAD(`c8f263d`)历史包含提交 `5e8318b Support full output path in doc2docx (#157)`,该提交已为 `doc2docx` 带来两处关键改动,**而 PR #154 的 diff 上下文里完全没有这些**: - -1. `output_name` 自动解析(#157 引入): - ```python - if output_name is None and Path(output_path).suffix.lower() == ".docx": - output_file = Path(output_path) - output_path = str(output_file.parent) - output_name = output_file.name - ``` -2. 全模块已改为 `_load_poword()` **延迟加载**(仅在调用时 `import poword`),避免 Windows 专用依赖在 `import office` 时触发 `ModuleNotFoundError`: - ```python - poword = _load_poword() - poword.doc2docx(input_path=input_path, output_path=output_path, output_name=output_name) - ``` - -PR #154 的改动却是直接把调用替换为 `poword.doc2docx(**kwargs)`(无 `_load_poword()`、无 `output_name` 解析)。 - -**后果(若直接合入)**: -- ❌ 丢失 #157 的 `output_name` 自动解析能力; -- ❌ 把延迟加载退回为直接调用 `poword`,**回归「非 Windows 环境 `import office` 因缺 poword 而崩溃」的已知风险**(这正是之前引入 `_load_poword` 要修的)。 - -**要求**:**rebase 到最新 `develop` 后再合入**,将 `show_progress` 逻辑叠加在现有 `doc2docdocx`(含 `_load_poword()` + `output_name` 解析)之上,例如: -```python -def doc2docx(input_path, output_path=r'./', output_name=None, show_progress=True): - if output_name is None and Path(output_path).suffix.lower() == ".docx": - ... - poword = _load_poword() - kwargs = {'input_path': input_path, 'output_path': output_path, 'output_name': output_name} - if not show_progress: - kwargs['show_progress'] = False - poword.doc2docx(**kwargs) -``` - -### 🟠 BLOCKER — 底层依赖 `poword#3` 未合并发布 -**依赖链**:`office.word.doc2docx(show_progress=False)` → `poword.doc2docx(show_progress=False)`(需 poword#3 提供) - -- 经核查,poword#3 页面仍为 `wants to merge ... into main` 措辞,**表明其处于 OPEN 状态、尚未合并到 `poword/main`,更未发布到 PyPI**。 -- `setup.cfg` 对 poword 的约束为 `poword;platform_system=='Windows'`,**无版本下限**。 -- **后果**:当前用户装到的 poword(旧版)`doc2docx` 大概率**不接受 `show_progress` 关键字**。本 PR 仅在 `show_progress=False` 时转发该键,因此: - - 默认调用(`show_progress=True`,不转发该键)✅ 仍兼容所有版本; - - 显式 `show_progress=False` ⚠️ 在旧版 poword 上极可能抛 `TypeError: unexpected keyword argument 'show_progress'`(除非旧版用 `**kwargs` 吞参,未验证)。 -- **要求**:至少满足其一再合入:(a) 等待 poword#3 合并并发布,且在 `setup.cfg` 提高 poword 版本下限(如 `poword>=x.y.z;platform_system=='Windows'`);或 (b) 在 `word.py` 内对 `show_progress=False` 做防御性转发(如先探测 poword 是否支持该参数,或对 `TypeError` 降级)。 - -### 🔵 实现质量(正面) -- `show_progress` 转发逻辑正确:默认不传键(兼容旧调用),仅 `False` 时传 `show_progress=False`。✅ -- 用 `kwargs` 构建参数,清晰且易维护。✅ -- `docstring` 与 `skills/word/doc2docx/SKILL.md` 同步更新(参数表 + 示例),文档一致性好。✅ - -### 📊 测试覆盖 -**新增** `tests/test_code/test_word_api_parameters.py`:`load_word_api()` 动态加载 `word.py` 并 mock `poword`,验证: -- 默认调用 → `poword.doc2docx(input_path, output_path, output_name)`(不含 `show_progress`)✅ -- `show_progress=False` → 含 `show_progress=False` ✅ - -覆盖到位,但**有缺口**: -- 测试基于 PR 改动后的 `doc2docx` 签名,未涉及 `output_name` 解析 + `show_progress` 的组合(rebase 到含 #157 的 develop 后建议补充,防止回归 #157 行为); -- 白盒加载方式依赖 `word.py` 顶部无顶层 `import poword`(当前满足),rebase 后若引入新顶层 import 需同步调整 mock。 - -### 安全与高危调用 -- 无硬编码凭据 / 密钥泄露 ✅ -- 无 `panic()` / `os._exit()` 等高危调用 ✅ -- 测试内 `print` 仅出现在 `if __name__ == "__main__":`,非生产路径 ✅ - -## 五、整体裁决 - -### 🟡 NEEDS ATTENTION(含两个 BLOCKER,合入前必须处理) - -**合入前置条件(缺一不可)**: -1. **Rebase 到最新 `develop`**:解决与 #157 的冲突,保留 `output_name` 解析与 `_load_poword()` 延迟加载,将 `show_progress` 叠加其上(否则会覆盖已有功能并回归 import 崩溃)。 -2. **落实底层依赖**:等待 `poword#3` 合并发布,并在 `setup.cfg` 设 poword 版本下限;或在 `word.py` 内做 `show_progress=False` 的防御性转发。 - -**次要建议**: -- 补充 `output_name` + `show_progress` 组合的单测; -- PR 描述已声明依赖 poword#3,建议在描述中标注其当前 OPEN 状态与预计合入节奏,便于维护者排期。 - -**优先级**:① rebase(阻断性,最高)→ ② 底层依赖落地 / 防御性转发 → ③ 测试补充。 - ---- -*生成时间:2026-08-04 | 审查人:PR 代码审查专家(本地静态分析,未发布 GitHub 评论)* diff --git a/PR-162-review.md b/PR-162-review.md deleted file mode 100644 index 9e510a24..00000000 --- a/PR-162-review.md +++ /dev/null @@ -1,105 +0,0 @@ -# PR #162 代码审查报告 — Fix compatibility check import side effects - -> 审查方式:基于 PR diff 静态分析(仓库本地已克隆,已核对引用关系) -> 注:`gh` CLI 未登录 GitHub,本报告未发布为 PR 评论。如需发布,请先 `gh auth login`。 - -## 一、PR 元数据 - -| 项 | 内容 | -|----|------| -| **标题** | Fix compatibility check import side effects | -| **作者** | [@echo-wee](https://github.com/echo-wee) | -| **源分支** | `echo-wee:fix-compatibility-mark-file-import` | -| **目标分支** | `CoderWanFeng:develop` | -| **变更文件** | 2 个(`office/compatibility.py`、`tests/test_code/test_optional_imports.py`) | -| **提交数** | 1 | -| **摘要** | ① 保护首次运行标记文件写入,避免 HOME 不可写时 import 崩溃;② 移除模块级兼容性检查以消除 import-time 副作用;③ 新增不可写场景的回归测试 | - -## 二、提交列表 - -- `fix compatibility check import side effects`(1 commit,含 `compatibility.py` + 测试 2 文件改动) - -## 三、变更文件概览 - -| 文件 | 类型 | 关键改动 | -|------|------|----------| -| `office/compatibility.py` | 修改 | `_check_first_run()` 包 try/except OSError;删除模块级 `compatibility_checker = check_compatibility()`;补文件结尾换行 | -| `tests/test_code/test_optional_imports.py` | 修改 | 新增 `test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written` | - -## 四、自动化发现 - -### 🟡 错误处理 — `_check_first_run` 保护(有效,符合目标①) -**文件**:`office/compatibility.py`(方法 `_check_first_run`,约 24–38 行) - -改动将 `mkdir` / `write_text` 包进 `try/except OSError`: -```python -try: - self.mark_file.parent.mkdir(exist_ok=True) - if not self.mark_file.exists(): - self.mark_file.write_text(f"First run on {platform.system()} at {platform.platform()}") - return True -except OSError: - # 兼容性提示不应影响主包导入;HOME 只读或不可写时跳过首次运行提示。 - return False -return False -``` -- `PermissionError` 是 `OSError` 子类,捕获范围正确;降级返回 `False`(当作非首次运行,静默跳过警告),不会阻断 `import office`。 -- **评价**:核心修复有效。因为真实调用路径是 `office/__init__.py:5` → `check_compatibility()` → `CrossPlatformCompatibility().__init__` → `_check_first_run()`,此保护对 `import office` 同样生效。 - -### 🟠 风险 — PR 描述与实际范围有偏差(建议澄清/进一步改进) -**文件**:`office/__init__.py:5` + `office/compatibility.py:239` - -PR 摘要称 *"Remove module-level compatibility checking to avoid import-time side effects"*,但本地核对发现: -- `office/__init__.py:5` **仍然存在** `compatibility_checker = check_compatibility()`。 -- `check_compatibility()`(compatibility.py:227)会:`CrossPlatformCompatibility()`(写标记文件)+ `display_warning()`(非 Windows 首次运行时打印 rich 表格)。 - -因此本次删除的只是 `compatibility.py` 自身的重复模块级调用(即 `ISSUES_AUDIT.md:221` 记录的"双重 rich 表格输出" bug 的第二次触发),**`import office` 的 import-time 副作用(写 `~/.python-office/first_run_mark` + 显示警告)在 `__init__.py:5` 仍保留**。 - -**影响**: -- 若目标仅是"修复 import 崩溃 + 去重",本 PR 已达成。 -- 若目标是"让 `import office` 完全无副作用",则未达成——`__init__.py:5` 仍在 import 时写文件并可能打印。 - -**建议**: -1. 在 PR 描述中澄清实际范围(消除 `compatibility.py` 的重复模块级检查,而非完全移除 import 副作用);或 -2. 若确实要彻底无副作用,应同时移除 `office/__init__.py:5` 的 `compatibility_checker = check_compatibility()`,改为延迟/按需调用(例如首次调用具体 API 时再检查)。 - -### 🔵 风格 / 小建议 -- **`compatibility.py` 结尾换行**:diff 补了缺失的 `\n`(`\ No newline at end of file` → 加换行),符合 POSIX 文本规范,👍。 -- **`build/lib/` 构建产物**:仓库中存在 `build/lib/office/compatibility.py` 与 `build/lib/office/__init__.py` 旧版副本(仍含模块级调用),属 setuptools 构建遗留物,不应纳入版本库。建议加入 `.gitignore` 或清理,避免与源码混淆。 - -### 📝 TODO(仓库卫生,非阻塞) -- `ISSUES_AUDIT.md:221` 记录了"双重 rich 表格输出"bug,本 PR 已修复该重复触发,建议在该审计文档中标注"已修复(PR #162)",避免后续复测重复扣分。 - -### 📊 测试覆盖 -**新增测试**:`test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written` -```python -def test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written(self): - with self._optional_import_test_environment(): - compatibility = importlib.import_module("office.compatibility") - with mock.patch.object(compatibility.Path, "mkdir", side_effect=PermissionError("readonly")): - checker = compatibility.CrossPlatformCompatibility() - self.assertFalse(checker.is_first_run) -``` -- 验证了 `mkdir` 抛 `PermissionError` 时实例化不崩溃且 `is_first_run == False`,命中 `except OSError` 分支。✅ -- **覆盖缺口**:测试直接 `import office.compatibility` 并实例化 `CrossPlatformCompatibility`,未覆盖真实的 `import office` 端到端路径(即 `__init__.py:5` → `check_compatibility()` → `display_warning()`)。由于逻辑等价(都走 `_check_first_run`),风险低,但建议补充一条 `import office` 在不可写场景下的冒烟测试,以锁住回归。 - -## 五、安全与高危调用检查 -- 无硬编码凭据 / 密钥泄露 ✅ -- 无 `panic()` / `os._exit()` / `process.exit()` 等高危调用 ✅ -- `print()` 仅出现在 `if __name__ == "__main__":` 测试块(compatibility.py:244-250),非生产路径 ✅ - -## 六、整体裁决 - -### 🟡 NEEDS ATTENTION - -**理由**:改动方向正确、核心修复(`_check_first_run` 的 OSError 保护)真实有效且安全,回归测试到位;但 PR 描述与实际生效范围存在偏差——真正的 import-time 副作用入口 `office/__init__.py:5` 未被触及。建议合入前: - -1. **澄清/对齐描述**:将"remove module-level compatibility checking to avoid import-time side effects"修正为"移除 `compatibility.py` 的重复模块级检查(消除双重提示),并保护标记文件写入"; -2. **(可选)彻底去副作用**:若项目确实要求 `import office` 零副作用,进一步移除 `office/__init__.py:5` 并改为延迟调用; -3. **补充** `import office` 端到端不可写冒烟测试; -4. **仓库卫生**:清理 `build/lib/` 构建产物、更新 `ISSUES_AUDIT.md` 标注。 - -**优先级排序**:① 描述澄清(必须,避免误解)→ ② 端到端测试(建议)→ ③ 彻底去副作用 / 仓库卫生(可选,后续跟进)。 - ---- -*生成时间:2026-08-04 | 审查人:PR 代码审查专家(本地静态分析,未发布 GitHub 评论)* diff --git a/README-CN.md b/README-CN.md deleted file mode 100644 index 9a69b46e..00000000 --- a/README-CN.md +++ /dev/null @@ -1,422 +0,0 @@ -
- -
-
-
-
-
- 🚀 一行代码,搞定办公自动化
-
- 73 个开箱即用的 Skills,覆盖 PDF、Word、Excel、PPT、邮件、微信、图片、视频等全场景
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如果这个项目对你有帮助,欢迎 ⭐ Star 支持一下! -
diff --git a/README-EN.md b/README-EN.md new file mode 100644 index 00000000..a431fd3b --- /dev/null +++ b/README-EN.md @@ -0,0 +1,191 @@ +
+
+
+
+
+ 🍬python for office +
++ 👉 http://www.python4office.cn/ 👈 +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- 🚀 Office automation, one line of code at a time
-
- 73 ready-to-use Skills covering PDF, Word, Excel, PPT, Email, WeChat, Images, Video and more
+ 👉 项目官网:https://www.python-office.com/ 👈
-
-
-
-
-
-
-
-
-
-
-
+ 👉 本开源项目的交流群 👈
+
+
+
+
+
+
+
+
+
+
+
+
----
-
-## ⚡ TL;DR
-
-> **python-office** is the most popular Python office-automation library in the Chinese-speaking world.
-> One library covers 90% of office scenarios: **PDF / Word / Excel / PPT conversion, image processing, video & audio, WeChat bot, email, file management, OCR, AI tools**...
-> Zero Python knowledge required — **every feature is one line of code**.
-
-```python
-pip install python-office
-```
-
-```python
-import office # one import, all features available
-```
-
----
-
-## ✨ Key Features
+
-
-
-
+
- 👉 Join the open-source community · - WeChat the author 👈 +
---- -- If this project helps you, a ⭐ Star is the best encouragement! +
+ diff --git a/allpackages.txt b/allpackages.txt index e07e8f83..9ec24eaa 100644 --- a/allpackages.txt +++ b/allpackages.txt @@ -1,189 +1,112 @@ about-time==4.2.1 -aiohappyeyeballs==2.6.1 -aiohttp==3.13.3 -aiosignal==1.4.0 -akshare==1.18.9 -alive-progress==3.3.0 -annotated-types==0.7.0 -anyio==4.12.1 -attrs==25.4.0 -Automat==25.4.16 -backports.tarfile==1.2.0 -beautifulsoup4==4.14.3 -cachetools==6.2.4 -certifi==2026.1.4 -cffi==2.0.0 -charset-normalizer==3.4.4 -click==8.3.1 +aiohttp==3.8.5 +aiosignal==1.3.1 +akshare==1.10.79 +alive-progress==3.1.4 +async-timeout==4.0.2 +attrs==23.1.0 +beautifulsoup4==4.12.2 +blinker==1.6.2 +certifi==2023.7.22 +charset-normalizer==3.2.0 +click==8.1.6 colorama==0.4.6 -comtypes==1.4.14 -constantly==23.10.4 -contourpy==1.3.3 -cryptography==46.0.3 -cssselect==1.3.0 -curl_cffi==0.14.0 -cycler==0.12.1 -decorator==5.2.1 -defusedxml==0.7.1 -Deprecated==1.3.1 -distro==1.9.0 -dnspython==2.8.0 -docutils==0.22.4 -dukpy==0.5.0 -et_xmlfile==2.0.0 -Faker==40.1.0 -filelock==3.20.3 -fire==0.7.1 -fonttools==4.61.1 -frozenlist==1.8.0 -graphemeu==0.7.2 -h11==0.16.0 +comtypes==1.2.0 +contourpy==1.1.0 +cycler==0.11.0 +decorator==4.4.2 +deprecation==2.1.0 +et-xmlfile==1.1.0 +Faker==19.3.0 +fire==0.5.0 +Flask==2.3.2 +fonttools==4.42.0 +fpdf==1.7.2 +frozenlist==1.4.0 +grapheme==0.6.0 html5lib==1.1 -httpcore==1.0.9 -httpx==0.28.1 -huaweicloudsdkcore==3.1.182 -huaweicloudsdkocr==3.1.182 -hyperlink==21.0.0 -id==1.5.0 -idna==3.11 -ImageIO==2.37.2 -imageio-ffmpeg==0.6.0 -importlib_metadata==8.7.1 -Incremental==24.11.0 -iniconfig==2.3.0 -itemadapter==0.13.1 -itemloaders==1.3.2 -jaraco.classes==3.4.0 -jaraco.context==6.0.2 -jaraco.functools==4.4.0 +idna==3.4 +imageio==2.31.1 +imageio-ffmpeg==0.4.8 +itsdangerous==2.1.2 jieba==0.42.1 -jiter==0.12.0 -jmespath==1.0.1 -jsonpath==0.82.2 -keyring==25.7.0 -kiwisolver==1.4.9 +Jinja2==3.1.2 +jsonpath==0.82 +kiwisolver==1.4.4 libretranslatepy==2.1.1 -loguru==0.7.3 -lxml==6.0.2 -markdown-it-py==4.0.0 -matplotlib==3.10.8 +lxml==4.9.3 +markdown-it-py==3.0.0 +MarkupSafe==2.1.3 +matplotlib==3.7.2 mdurl==0.1.2 -mini-racer==0.14.0 -more-itertools==10.8.0 -moviepy==2.2.1 -multidict==6.7.0 -nest-asyncio==1.6.0 -nh3==0.3.2 -numpy==2.2.6 -openai==2.15.0 -opencv-python==4.12.0.88 -opencv-python-headless==4.12.0.88 -openpyxl==3.1.5 -packaging==25.0 -pandas==2.3.3 -parsel==1.10.0 -pdf2docx==0.5.8 -pillow==11.3.0 -pluggy==1.6.0 -poai==0.0.12 -pocode==0.0.3 -poemail==0.1.0 -poexcel==0.0.22 -pofile==0.1.5 -poimage==0.0.22 -pomarkdown==0.0.3 -poocr==1.0.6 -popdf @ file:///D:/workplace/code/gitcode/popdf +moviepy==1.0.3 +multidict==6.0.4 +numpy==1.25.2 +openai==0.27.8 +opencv-python==4.8.0.76 +openpyxl==3.1.2 +packaging==23.1 +pandas==2.0.3 +pdf2docx==0.5.6 +pikepdf==8.2.3 +Pillow==10.0.0 +poai==0.0.8 +poexcel==0.0.15 +pofile==0.1.0 +poimage==0.0.12 +popdf==0.0.10 poppt==0.1.1 poprogress==0.0.2 porobot==0.0.3 -pospider==0.0.1 -potx-cloud==0.0.7 -povideo==0.0.8 -poword==0.0.17 -proglog==0.1.12 -propcache==0.4.1 -Protego==0.5.0 -psutil==7.2.1 -pyasn1==0.6.1 -pyasn1_modules==0.4.2 -pycparser==2.23 -pydantic==2.12.5 -pydantic_core==2.41.5 -PyDispatcher==2.0.7 -PyEmail==0.0.1 -Pygments==2.19.2 -PyJWT==2.8.0 -pymongo==4.16.0 -PyMuPDF==1.26.7 -PyOfficeRobot==0.1.26 -pyOpenSSL==25.3.0 -pyparsing==3.3.1 -pypdf==6.6.0 +povideo==0.0.5 +poword==0.0.12 +proglog==0.1.10 +py-mini-racer==0.6.0 +pydatav @ file:///D:/workplace/code/github/pydatav +Pygments==2.16.1 +PyMuPDF==1.22.5 +PyOfficeRobot==0.1.14 +pyparsing==3.0.9 PyPDF2==3.0.1 -pypiwin32==223 -PySide6==6.10.1 -PySide6_Addons==6.10.1 -PySide6_Essentials==6.10.1 -pytest==9.0.2 -python-dateutil==2.9.0.post0 -python-docx==1.2.0 -python-dotenv==1.2.1 -python-office @ file:///D:/workplace/code/github/python-office -python-pptx==1.0.2 -pyttsx3==2.99 -pytz==2025.2 +pypinyin==0.49.0 +pypng==0.20220715.0 +PySide6==6.5.2 +PySide6-Addons==6.5.2 +PySide6-Essentials==6.5.2 +python-dateutil==2.8.2 +python-docx==0.8.11 +python-office==0.3.20 +python-pptx==0.6.21 +pytz==2023.3 pywifi==1.1.12 -pywin32==311 -pywin32-ctypes==0.2.3 -pywinauto==0.6.9 -PyYAML==6.0.3 -qrcode==8.2 -queuelib==1.8.0 -readme_renderer==44.0 -requests==2.32.5 -requests-file==3.0.1 -requests-toolbelt==1.0.0 -rfc3986==2.0.0 -rich==14.2.0 -schedule==1.2.2 -Scrapy==2.14.0 +pywin32==306 +pywinauto==0.6.8 +qrcode==7.4.2 +reportlab==4.0.4 +requests==2.31.0 +rich==13.5.2 +schedule==1.2.0 search4file==0.1.15 -service-identity==24.2.0 -shiboken6==6.10.1 -simplejson==3.20.2 -six==1.17.0 -sniffio==1.3.1 -soupsieve==2.8.1 +shiboken6==6.5.2 +six==1.16.0 +soupsieve==2.4.1 speedtest-cli==2.1.3 tabulate==0.9.0 -tencentcloud-sdk-python==3.1.29 -tencentcloud-sdk-python-common==3.1.29 -tencentcloud-sdk-python-ocr==3.1.29 -termcolor==3.3.0 -tldextract==5.3.1 -toml==0.10.2 -tqdm==4.67.1 -translate==3.8.0 -twine==6.2.0 -Twisted==25.5.0 -typing-inspection==0.4.2 -typing_extensions==4.15.0 -tzdata==2025.3 -uiautomation==2.0.29 -urllib3==2.6.3 -w3lib==2.3.1 +tencentcloud-sdk-python==3.0.954 +termcolor==2.3.0 +tqdm==4.66.0 +translate==3.6.1 +typing_extensions==4.7.1 +tzdata==2023.3 +uiautomation==2.0.18 +urllib3==2.0.4 webencodings==0.5.1 -wftools==0.0.10 -win32_setctime==1.2.0 -wordcloud==1.9.5 -wrapt==2.0.1 +Werkzeug==2.3.6 +wftools==0.0.6 +wordcloud==1.9.2 xlrd==1.2.0 -xlsxwriter==3.2.9 -xlwings==0.33.19 +XlsxWriter==3.1.2 +xlwings==0.30.10 xlwt==1.3.0 -yarl==1.22.0 -you-get==0.4.1743 -zhipuai==2.1.5.20250825 -zipp==3.23.0 -zope.interface==8.2 +yarl==1.9.2 +you-get==0.4.1650 diff --git a/contributors/77x2 b/contributors/77x2 deleted file mode 100644 index 5b9fd2b8..00000000 --- a/contributors/77x2 +++ /dev/null @@ -1 +0,0 @@ -qinandenixiangnwom diff --git a/contributors/CatchDr/Baidu_Text_transAPI.py b/contributors/CatchDr/Baidu_Text_transAPI.py index 2889384b..b6aa0c84 100644 --- a/contributors/CatchDr/Baidu_Text_transAPI.py +++ b/contributors/CatchDr/Baidu_Text_transAPI.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -10,30 +11,10 @@ import requests import random from hashlib import md5 -def make_md5(s: str, encoding: str = 'utf-8') -> str: - """生成字符串的MD5哈希值。 - - Args: - s (str): 要哈希的字符串 - encoding (str, optional): 编码格式,默认为'utf-8' - - Returns: - str: MD5哈希值 - """ +def make_md5(s, encoding='utf-8'): return md5(s.encode(encoding)).hexdigest() -def baidu_trans(query, from_lang, to_lang, appid, appkey): - """调用百度翻译接口进行翻译。 - - Args: - query (str): 需要翻译的文本 - from_lang (str): 源语言代码 - to_lang (str): 目标语言代码 - appid (str): 百度翻译API的应用ID - appkey (str): 百度翻译API的密钥 - - Returns: - str: 翻译后的文本 - """ +def baidu_trans(query,from_lang,to_lang,appid,appkey): + # Set your own appid/appkey. # For list of language codes, please refer to `https://api.fanyi.baidu.com/doc/21` diff --git a/contributors/CatchDr/doc2docx.py b/contributors/CatchDr/doc2docx.py index 93c51112..586518bf 100644 --- a/contributors/CatchDr/doc2docx.py +++ b/contributors/CatchDr/doc2docx.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -13,13 +14,7 @@ import os # 目录的操作 -def createdocx(wordPath: str, docxPath: str) -> None: - """将Word文档转换为docx格式。 - - Args: - wordPath (str): 原始Word文档路径 - docxPath (str): 转换后的docx文件路径 - """ +def createdocx(wordPath, docxPath): # word = gencache.EnsureDispatch('Word.Application') # doc = word.Documents.Open(wordPath, ReadOnly=1) # # 转换方法 @@ -33,13 +28,10 @@ def createdocx(wordPath: str, docxPath: str) -> None: word.Quit() -def doc2docx(path: str, docSuffix: str = ".doc") -> None: - """批量将doc文件转换为docx格式。 - - Args: - path (str): 文件路径或目录路径 - docSuffix (str, optional): doc文件后缀,默认为".doc" - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换doc到docx +def doc2docx(path, docSuffix=".doc"): wordFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/CatchDr/docx2doc.py b/contributors/CatchDr/docx2doc.py index e06efc24..b31d3bd3 100644 --- a/contributors/CatchDr/docx2doc.py +++ b/contributors/CatchDr/docx2doc.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -14,16 +15,7 @@ -def createdoc(wordPath: str, docxPath: str) -> None: - """将Word文档转换为DOC格式。 - - Args: - wordPath (str): 源Word文档路径 - docxPath (str): 目标DOC文档路径 - - Returns: - None - """ +def createdoc(wordPath, docxPath): # word = gencache.EnsureDispatch('Word.Application') # doc = word.Documents.Open(wordPath, ReadOnly=1) # # 转换方法 @@ -37,16 +29,10 @@ def createdoc(wordPath: str, docxPath: str) -> None: word.Quit() -def docx2doc(path: str, docxSuffix: str = ".docx") -> None: - """批量将DOCX文档转换为DOC格式。 - - Args: - path (str): 文件路径或目录路径 - docxSuffix (str, optional): DOCX文件后缀名,默认为".docx" - - Returns: - None - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换docx到doc +def docx2doc(path, docxSuffix=".docx"): wordFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/CatchDr/ppt2pptx.py b/contributors/CatchDr/ppt2pptx.py index 68ec6ca2..93b26ce8 100644 --- a/contributors/CatchDr/ppt2pptx.py +++ b/contributors/CatchDr/ppt2pptx.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -12,16 +13,7 @@ import win32com import os # 目录的操作 -def createpptx(pptPath: str, pptxPath: str) -> None: - """将PPT文档转换为PPTX格式。 - - Args: - pptPath (str): 源PPT文档路径 - pptxPath (str): 目标PPTX文档路径 - - Returns: - None - """ +def createpptx(pptPath, pptxPath): powerpoint = win32com.client.Dispatch('PowerPoint.Application') win32com.client.gencache.EnsureDispatch('PowerPoint.Application') # powerpoint.Visible = 1 @@ -31,16 +23,10 @@ def createpptx(pptPath: str, pptxPath: str) -> None: powerpoint.Quit() -def ppt2pptx(path: str, docxSuffix: str = ".poppt") -> None: - """批量将PPT文档转换为PPTX格式。 - - Args: - path (str): 文件路径或目录路径 - docxSuffix (str, optional): PPT文件后缀名,默认为".poppt" - - Returns: - None - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换ppt到pptx +def ppt2pptx(path, docxSuffix=".poppt"): pptFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/CatchDr/pptx2ppt.py b/contributors/CatchDr/pptx2ppt.py index ce147b88..c0cd8da7 100644 --- a/contributors/CatchDr/pptx2ppt.py +++ b/contributors/CatchDr/pptx2ppt.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -12,16 +13,7 @@ import win32com import os # 目录的操作 -def createppt(pptxPath: str, pptPath: str) -> None: - """将PPTX文档转换为PPT格式。 - - Args: - pptxPath (str): 源PPTX文档路径 - pptPath (str): 目标PPT文档路径 - - Returns: - None - """ +def createppt(pptxPath, pptPath): powerpoint = win32com.client.Dispatch('PowerPoint.Application') win32com.client.gencache.EnsureDispatch('PowerPoint.Application') # powerpoint.Visible = 1 @@ -31,16 +23,10 @@ def createppt(pptxPath: str, pptPath: str) -> None: powerpoint.Quit() -def pptx2ppt(path: str, docxSuffix: str = ".pptx") -> None: - """批量将PPTX文档转换为PPT格式。 - - Args: - path (str): 文件路径或目录路径 - docxSuffix (str, optional): PPTX文件后缀名,默认为".pptx" - - Returns: - None - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换pptx到ppt +def pptx2ppt(path, docxSuffix=".pptx"): pptxFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/CatchDr/video_time_statistics.py b/contributors/CatchDr/video_time_statistics.py index 3936fb44..10327b03 100644 --- a/contributors/CatchDr/video_time_statistics.py +++ b/contributors/CatchDr/video_time_statistics.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -11,15 +12,7 @@ import datetime from moviepy.editor import VideoFileClip from tqdm import tqdm -def video_time_statistics(path: str) -> None: - """统计指定目录下所有MP4视频文件的总时长。 - - Args: - path (str): 要统计视频时长的目录路径 - - Returns: - None - """ +def video_time_statistics(path): filelist = [] for a, b, c in os.walk(path): for name in c: diff --git a/contributors/CatchDr/xls2xlsx.py b/contributors/CatchDr/xls2xlsx.py index c97295f8..a4876370 100644 --- a/contributors/CatchDr/xls2xlsx.py +++ b/contributors/CatchDr/xls2xlsx.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -14,16 +15,8 @@ -def createxlsx(xlsPath: str, xlsxPath: str) -> None: - """将XLS文档转换为XLSX格式。 - - Args: - xlsPath (str): 源XLS文档路径 - xlsxPath (str): 目标XLSX文档路径 - - Returns: - None - """ +def createxlsx(xlsPath, xlsxPath): + excel = win32com.client.DispatchEx('Excel.Application') wb = excel.Workbooks.Open(xlsPath) @@ -33,16 +26,10 @@ def createxlsx(xlsPath: str, xlsxPath: str) -> None: -def xls2xlsx(path: str, docxSuffix: str = ".xls") -> None: - """批量将XLS文档转换为XLSX格式。 - - Args: - path (str): 文件路径或目录路径 - docxSuffix (str, optional): XLS文件后缀名,默认为".xls" - - Returns: - None - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换xls到xlsx +def xls2xlsx(path, docxSuffix=".xls"): excelFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/CatchDr/xlsx2xls.py b/contributors/CatchDr/xlsx2xls.py index 55381a1e..0632141a 100644 --- a/contributors/CatchDr/xlsx2xls.py +++ b/contributors/CatchDr/xlsx2xls.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################# @@ -12,16 +13,8 @@ import win32com import os # 目录的操作 -def createxls(xlsxPath: str, xlsPath: str) -> None: - """将XLSX文档转换为XLS格式。 - - Args: - xlsxPath (str): 源XLSX文档路径 - xlsPath (str): 目标XLS文档路径 - - Returns: - None - """ +def createxls(xlsxPath, xlsPath): + excel = win32com.client.DispatchEx('Excel.Application') wb = excel.Workbooks.Open(xlsxPath) @@ -30,16 +23,10 @@ def createxls(xlsxPath: str, xlsPath: str) -> None: excel.Application.Quit() -def xlsx2xls(path: str, docxSuffix: str = ".xlsx") -> None: - """批量将XLSX文档转换为XLS格式。 - - Args: - path (str): 文件路径或目录路径 - docxSuffix (str, optional): XLSX文件后缀名,默认为".xlsx" - - Returns: - None - """ +# 1、文件的批量转换 +# 自己指定路径, +# 转换xlsx到xls +def xlsx2xls(path, docxSuffix=".xlsx"): excelFiles = [] # 如果不存在,则不做处理 if not os.path.exists(path): diff --git a/contributors/NWTNaldo/merge_docx_fix.py b/contributors/NWTNaldo/merge_docx_fix.py deleted file mode 100644 index 94884739..00000000 --- a/contributors/NWTNaldo/merge_docx_fix.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import re -from docx import Document -from docxcomposer import Composer - -def merge4docx(input_path: str, output_path: str, new_word_name: str = "merged.docx") -> str: - """ - 合并指定文件夹下的所有 .docx 文件 - - :param input_path: 输入 Word 文件的文件夹路径 - :param output_path: 合并后 Word 文件的输出文件夹路径 - :param new_word_name: 合并后的新文件名(如 "111.docx") - :return: 合并后文件的完整输出路径 - """ - # 1. 自动处理目录路径与创建 - if not os.path.exists(output_path): - os.makedirs(output_path, exist_ok=True) - - # 2. 规范化文件名(防止重复拼接 .docx 后缀) - if not new_word_name.lower().endswith('.docx'): - new_word_name = f"{new_word_name}.docx" - - final_output_file = os.path.join(output_path, new_word_name) - - # 3. 过滤临时文件(以 ~$ 开头)并仅保留 .docx 格式文件 - all_files = [ - f for f in os.listdir(input_path) - if f.lower().endswith('.docx') and not f.startswith('~$') - ] - - # 4. 自然排序算法(确保 1.docx, 2.docx, 10.docx 按常规数字顺序合并) - def natural_sort_key(filename: str): - return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', filename)] - - all_files.sort(key=natural_sort_key) - - if not all_files: - raise FileNotFoundError(f"在路径 '{input_path}' 下未找到有效的 .docx 文件") - - # 5. 排除输出文件本身(防止同目录合并时递归循环) - files_to_merge = [] - for file in all_files: - full_path = os.path.abspath(os.path.join(input_path, file)) - if full_path == os.path.abspath(final_output_file): - continue - files_to_merge.append(full_path) - - if not files_to_merge: - raise ValueError("没有可用于合并的目标文件") - - # 6. 以第一个文件为主文档初始化 Composer - master_doc = Document(files_to_merge[0]) - composer = Composer(master_doc) - - # 7. 依次合并后续文件并添加分页符 - for file_path in files_to_merge[1:]: - doc_to_append = Document(file_path) - master_doc.add_page_break() # 在文档末尾追加分页 - composer.append(doc_to_append) - - # 8. 保存合并后的文档 - composer.save(final_output_file) - return final_output_file diff --git a/contributors/bulabean/SearchExcel.py b/contributors/bulabean/SearchExcel.py index 90a6521f..998b7567 100644 --- a/contributors/bulabean/SearchExcel.py +++ b/contributors/bulabean/SearchExcel.py @@ -6,13 +6,10 @@ def change_datatype(row_data: list): - """Excel单元格的内容类型检测和转换。 - - Args: - row_data (list): 行数据,列表格式 - - Returns: - list: 转换后的行数据 + """ + excel单元格的内容类型检测和转换 + 参数: + row_data:行数据,列表格式 """ result_data = [] for rd in row_data: @@ -33,14 +30,11 @@ def change_datatype(row_data: list): def find_key(search_key: str, row_content: str): - """检测关键词和内容。 - - Args: - search_key (str): 关键词 - row_content (str): 行内容 - - Returns: - bool: 如果包含关键词返回True,否则返回False + """ + 检测关键词和内容 + 参数: + search_key:关键词 + row_content:行内容 """ if search_key in row_content: return True @@ -49,14 +43,11 @@ def find_key(search_key: str, row_content: str): def process_xls(path, file): - """读取xls后缀的Excel文件。 - - Args: - path (str): 文件所在路径 - file (str): 文件名 - - Yields: - tuple: 包含文件路径、工作表名、行数、行内容的元组 + """ + 读取xls后缀的excel文件 + 参数: + path:文件所在路径 + file:文件名 """ filepath = os.path.join(path, file) try: @@ -83,14 +74,11 @@ def process_xls(path, file): def process_xlsx(path, file): - """读取xlsx后缀的Excel文件。 - - Args: - path (str): 文件所在路径 - file (str): 文件名 - - Yields: - tuple: 包含文件路径、工作表名、行数、行内容的元组 + """ + 读取xlsx后缀的excel文件 + 参数: + path:文件所在路径 + file:文件名 """ filepath = os.path.join(path, file) try: @@ -115,14 +103,11 @@ def process_xlsx(path, file): def find_excel_data(search_key: str, target_dir: str): - """检索指定目录下的Excel文件和过滤。 - - Args: - search_key (str): 检索的关键词 - target_dir (str): 目标文件夹 - - Yields: - tuple: 包含文件路径、工作表名、行数、行内容的元组 + """ + 检索指定目录下的excel文件和过滤 + 参数: + search_key:检索的关键词 + target_dir:目标文件夹 """ for path, dirs, files in os.walk(target_dir): files = [file for file in files if not file.startswith('~$')] # 过滤掉正打开的excel文件 diff --git a/contributors/bulabean/SplitExcel.py b/contributors/bulabean/SplitExcel.py index d123c738..717dfc41 100644 --- a/contributors/bulabean/SplitExcel.py +++ b/contributors/bulabean/SplitExcel.py @@ -4,17 +4,9 @@ import datetime +# -def generate_xls(filepath: str, worksheet_data: dict) -> str: - """生成新的xls文件。 - - Args: - filepath (str): 原始文件路径 - worksheet_data (dict): 工作表数据字典 - - Returns: - str: 新生成的文件路径 - """ +def generate_xls(filepath: str, worksheet_data: dict): datetime_str = datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S') new_filepath = filepath.replace('.xls', '_Split_{}.xls'.format(datetime_str)) new_workbook = xlwt.Workbook(encoding='utf-8') @@ -27,17 +19,7 @@ def generate_xls(filepath: str, worksheet_data: dict) -> str: return new_filepath -def process_xls(filepath: str, column: int, worksheet_name: str = None) -> str: - """处理xls格式的Excel文件。 - - Args: - filepath (str): Excel文件路径 - column (int): 要拆分的列号 - worksheet_name (str, optional): 工作表名称,默认为第一个工作表 - - Returns: - str: 处理结果信息 - """ +def process_xls(filepath, column: int, worksheet_name: str = None): try: workbook = xlrd.open_workbook(filepath, formatting_info=True) except: @@ -59,16 +41,7 @@ def process_xls(filepath: str, column: int, worksheet_name: str = None) -> str: return "数据保存在新文件中,文件名:{}".format(new_filepath) -def generate_xlsx(filepath: str, worksheet_data: dict) -> str: - """生成新的xlsx文件。 - - Args: - filepath (str): 原始文件路径 - worksheet_data (dict): 工作表数据字典 - - Returns: - str: 新生成的文件路径 - """ +def generate_xlsx(filepath: str, worksheet_data: dict): datetime_str = datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S') new_filepath = filepath.replace('.xlsx', '_Split_{}.xlsx'.format(datetime_str)) new_workbook = openpyxl.Workbook() @@ -80,17 +53,7 @@ def generate_xlsx(filepath: str, worksheet_data: dict) -> str: return new_filepath -def process_xlsx(filepath: str, column: int, worksheet_name: str = None) -> str: - """处理xlsx格式的Excel文件。 - - Args: - filepath (str): Excel文件路径 - column (int): 要拆分的列号 - worksheet_name (str, optional): 工作表名称,默认为活动工作表 - - Returns: - str: 处理结果信息 - """ +def process_xlsx(filepath: str, column: int, worksheet_name: str = None): try: workbook = openpyxl.load_workbook(filepath, read_only=True, data_only=True) except: @@ -113,17 +76,7 @@ def process_xlsx(filepath: str, column: int, worksheet_name: str = None) -> str: return "数据保存在新文件中,文件名:{}".format(new_filepath) -def split_excel(filepath: str, column: int, worksheet_name: str = None) -> str: - """拆分Excel文件根据指定列。 - - Args: - filepath (str): Excel文件路径 - column (int): 要拆分的列号 - worksheet_name (str, optional): 工作表名称 - - Returns: - str: 处理结果信息 - """ +def split_excel(filepath: str, column: int, worksheet_name: str = None): if filepath.endswith('.xlsx'): result = process_xlsx(filepath, column, worksheet_name) elif filepath.endswith('.xls'): diff --git a/contributors/bulabean/sedemo.xls b/contributors/bulabean/sedemo.xls index 9b0349eb..dfc3e03b 100644 Binary files a/contributors/bulabean/sedemo.xls and b/contributors/bulabean/sedemo.xls differ diff --git a/contributors/bulabean/sedemo_Split_2022-08-23_203011.xls b/contributors/bulabean/sedemo_Split_2022-08-23_203011.xls index 7234001e..bb620692 100644 Binary files a/contributors/bulabean/sedemo_Split_2022-08-23_203011.xls and b/contributors/bulabean/sedemo_Split_2022-08-23_203011.xls differ diff --git a/contributors/bulabean/sedemo_Split_2022-08-23_203413.xls b/contributors/bulabean/sedemo_Split_2022-08-23_203413.xls index cabc6f0d..bb620692 100644 Binary files a/contributors/bulabean/sedemo_Split_2022-08-23_203413.xls and b/contributors/bulabean/sedemo_Split_2022-08-23_203413.xls differ diff --git a/contributors/bulabean/sedemo_Split_2022-09-17_154536.xls b/contributors/bulabean/sedemo_Split_2022-09-17_154536.xls index 407d984d..bb620692 100644 Binary files a/contributors/bulabean/sedemo_Split_2022-09-17_154536.xls and b/contributors/bulabean/sedemo_Split_2022-09-17_154536.xls differ diff --git a/contributors/bulabean/sedemo_Split_2025-02-23_183018.xls b/contributors/bulabean/sedemo_Split_2025-02-23_183018.xls deleted file mode 100644 index bb620692..00000000 Binary files a/contributors/bulabean/sedemo_Split_2025-02-23_183018.xls and /dev/null differ diff --git a/contributors/david3832024-coder/README.md b/contributors/david3832024-coder/README.md deleted file mode 100644 index 0ee921e1..00000000 --- a/contributors/david3832024-coder/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Batch Image Converter - -This contribution adds a Pillow-based helper for batch image conversion. - -## Features - -- Convert JPG, PNG, BMP, WEBP, TIFF, and GIF files in batch. -- Optionally resize images to a fixed canvas. -- Preserve RGBA transparency for formats that support it. -- Fill resized images with white or transparent background. -- Create animated GIF files with configurable frame duration. - -## Install dependency - -```bash -pip install Pillow -``` - -## Command line usage - -Convert all images in a folder to PNG: - -```bash -python batch_image_converter.py convert ./images ./output --format png -``` - -Convert to WEBP and resize to an 800x600 canvas: - -```bash -python batch_image_converter.py convert ./images ./output --format webp --size 800x600 -``` - -Create an animated GIF: - -```bash -python batch_image_converter.py gif ./images ./output/demo.gif --duration 300 -``` - -## Python usage - -```python -from batch_image_converter import convert_images, create_gif - -convert_images( - input_path="./images", - output_dir="./output", - output_format="png", - size=(800, 600), - background="transparent", -) - -create_gif( - input_path="./images", - output_file="./output/demo.gif", - duration=300, - size=(800, 600), -) -``` diff --git a/contributors/david3832024-coder/batch_image_converter.py b/contributors/david3832024-coder/batch_image_converter.py deleted file mode 100644 index 02d9dcb4..00000000 --- a/contributors/david3832024-coder/batch_image_converter.py +++ /dev/null @@ -1,244 +0,0 @@ -"""Batch image conversion helper based on Pillow. - -Features: -- convert images between JPG, PNG, BMP, WEBP, TIFF, and GIF -- resize images with optional aspect-ratio padding -- preserve RGBA when the target format supports transparency -- compose multiple images into an animated GIF -""" - -from __future__ import annotations - -import argparse -from pathlib import Path -from typing import Iterable, List, Optional, Sequence, Tuple - -from PIL import Image, ImageSequence - - -SUPPORTED_FORMATS = {"jpg", "jpeg", "png", "bmp", "webp", "tiff", "gif"} -TRANSPARENT_FORMATS = {"png", "webp", "tiff", "gif"} - - -def _normalize_format(image_format: str) -> str: - image_format = image_format.lower().lstrip(".") - if image_format not in SUPPORTED_FORMATS: - raise ValueError(f"Unsupported image format: {image_format}") - return "jpeg" if image_format == "jpg" else image_format - - -def _parse_size(size: Optional[str]) -> Optional[Tuple[int, int]]: - if not size: - return None - width, height = size.lower().split("x", maxsplit=1) - return int(width), int(height) - - -def _background_color(mode: str, background: str): - if background == "transparent": - return (255, 255, 255, 0) if mode == "RGBA" else 0 - return "white" - - -def _iter_image_files(input_path: Path, include_subfolders: bool = False) -> List[Path]: - if input_path.is_file(): - return [input_path] - - pattern = "**/*" if include_subfolders else "*" - files = [ - file_path - for file_path in input_path.glob(pattern) - if file_path.is_file() - and file_path.suffix.lower().lstrip(".") in SUPPORTED_FORMATS - ] - return sorted(files) - - -def _flatten_alpha(image: Image.Image, background: str = "white") -> Image.Image: - if image.mode not in ("RGBA", "LA"): - return image.convert("RGB") - - rgba_image = image.convert("RGBA") - canvas = Image.new("RGBA", rgba_image.size, _background_color("RGBA", background)) - canvas.alpha_composite(rgba_image) - return canvas.convert("RGB") - - -def _resize_with_canvas( - image: Image.Image, - size: Optional[Tuple[int, int]], - background: str = "white", - keep_aspect_ratio: bool = True, -) -> Image.Image: - if size is None: - return image.copy() - - if not keep_aspect_ratio: - return image.resize(size, Image.LANCZOS) - - resized = image.copy() - resized.thumbnail(size, Image.LANCZOS) - mode = "RGBA" if resized.mode in ("RGBA", "LA") else "RGB" - canvas = Image.new(mode, size, _background_color(mode, background)) - left = (size[0] - resized.width) // 2 - top = (size[1] - resized.height) // 2 - - if resized.mode in ("RGBA", "LA"): - canvas.paste(resized.convert("RGBA"), (left, top), resized.convert("RGBA")) - else: - canvas.paste(resized.convert(mode), (left, top)) - - return canvas - - -def _prepare_image( - image: Image.Image, - output_format: str, - size: Optional[Tuple[int, int]] = None, - background: str = "white", - keep_aspect_ratio: bool = True, -) -> Image.Image: - first_frame = next(ImageSequence.Iterator(image)).copy() - first_frame = _resize_with_canvas( - first_frame, size=size, background=background, keep_aspect_ratio=keep_aspect_ratio - ) - - if output_format not in TRANSPARENT_FORMATS: - return _flatten_alpha(first_frame, background=background) - - if first_frame.mode not in ("RGBA", "RGB"): - first_frame = first_frame.convert("RGBA") - return first_frame - - -def convert_images( - input_path: str, - output_dir: str, - output_format: str = "png", - size: Optional[Tuple[int, int]] = None, - background: str = "white", - keep_aspect_ratio: bool = True, - include_subfolders: bool = False, - overwrite: bool = True, -) -> List[Path]: - """Batch-convert images and return generated file paths.""" - source = Path(input_path) - target_dir = Path(output_dir) - output_format = _normalize_format(output_format) - target_dir.mkdir(parents=True, exist_ok=True) - - output_files: List[Path] = [] - for image_file in _iter_image_files(source, include_subfolders=include_subfolders): - output_file = target_dir / f"{image_file.stem}.{output_format}" - if output_file.exists() and not overwrite: - continue - - with Image.open(image_file) as image: - converted = _prepare_image( - image, - output_format=output_format, - size=size, - background=background, - keep_aspect_ratio=keep_aspect_ratio, - ) - converted.save(output_file, format=output_format.upper()) - - output_files.append(output_file) - - return output_files - - -def create_gif( - input_path: str, - output_file: str, - duration: int = 500, - size: Optional[Tuple[int, int]] = None, - background: str = "white", - include_subfolders: bool = False, - loop: int = 0, -) -> Path: - """Create an animated GIF from images in a file or directory.""" - image_files = _iter_image_files(Path(input_path), include_subfolders=include_subfolders) - if not image_files: - raise ValueError("No images found for GIF creation.") - - frames = [] - for image_file in image_files: - with Image.open(image_file) as image: - frame = _prepare_image( - image, - output_format="gif", - size=size, - background=background, - keep_aspect_ratio=True, - ) - frames.append(frame.convert("P", palette=Image.ADAPTIVE)) - - gif_path = Path(output_file) - gif_path.parent.mkdir(parents=True, exist_ok=True) - frames[0].save( - gif_path, - save_all=True, - append_images=frames[1:], - duration=duration, - loop=loop, - ) - return gif_path - - -def _build_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(description="Batch image converter based on Pillow.") - subparsers = parser.add_subparsers(dest="command", required=True) - - convert_parser = subparsers.add_parser("convert", help="Batch convert image format.") - convert_parser.add_argument("input_path", help="Input file or directory.") - convert_parser.add_argument("output_dir", help="Directory for converted images.") - convert_parser.add_argument("--format", default="png", help="Output format.") - convert_parser.add_argument("--size", help="Resize target, for example 800x600.") - convert_parser.add_argument("--background", default="white", choices=["white", "transparent"]) - convert_parser.add_argument("--stretch", action="store_true", help="Resize without padding.") - convert_parser.add_argument("--include-subfolders", action="store_true") - convert_parser.add_argument("--skip-existing", action="store_true") - - gif_parser = subparsers.add_parser("gif", help="Create animated GIF from images.") - gif_parser.add_argument("input_path", help="Input file or directory.") - gif_parser.add_argument("output_file", help="Output GIF path.") - gif_parser.add_argument("--duration", type=int, default=500, help="Frame duration in ms.") - gif_parser.add_argument("--size", help="Resize target, for example 800x600.") - gif_parser.add_argument("--background", default="white", choices=["white", "transparent"]) - gif_parser.add_argument("--include-subfolders", action="store_true") - - return parser - - -def main(argv: Optional[Sequence[str]] = None) -> None: - args = _build_parser().parse_args(argv) - size = _parse_size(args.size) - - if args.command == "convert": - results = convert_images( - input_path=args.input_path, - output_dir=args.output_dir, - output_format=args.format, - size=size, - background=args.background, - keep_aspect_ratio=not args.stretch, - include_subfolders=args.include_subfolders, - overwrite=not args.skip_existing, - ) - print(f"Converted {len(results)} image(s).") - return - - gif_path = create_gif( - input_path=args.input_path, - output_file=args.output_file, - duration=args.duration, - size=size, - background=args.background, - include_subfolders=args.include_subfolders, - ) - print(f"Created GIF: {gif_path}") - - -if __name__ == "__main__": - main() diff --git a/contributors/demo/WordType.py b/contributors/demo/WordType.py index 87f0325f..2feaa2c6 100644 --- a/contributors/demo/WordType.py +++ b/contributors/demo/WordType.py @@ -7,10 +7,7 @@ # pip install -i https://mirrors.aliyun.com/pypi/simple/ pypiwin32 class MainWord(): - """Word文档处理类,用于将Word文档转换为PDF格式。""" - - def __init__(self) -> None: - """初始化Word应用程序连接。""" + def __init__(self): self.doc = ".doc" self.docx = ".docx" self.pdf = ".popdf" @@ -18,15 +15,7 @@ def __init__(self) -> None: self.word = client.Dispatch("Word.Application") - def file2pdf(self, path: str) -> None: - """将指定目录下的所有Word文档转换为PDF格式。 - - Args: - path (str): 包含Word文档的目录路径 - - Returns: - None - """ + def file2pdf(self, path): # 保存待转换的word文件 word_files = [] @@ -64,16 +53,7 @@ def file2pdf(self, path: str) -> None: for f in remove_files: os.remove(f) - def createpdf(self, word_path: str, pdf_path: str) -> None: - """将单个Word文档转换为PDF格式。 - - Args: - word_path (str): 源Word文档路径 - pdf_path (str): 目标PDF文档路径 - - Returns: - None - """ + def createpdf(self, word_path, pdf_path): print(word_path) try: doc = self.word.Documents.Open(word_path, ReadOnly=1) diff --git a/contributors/heyi/About_hy.md b/contributors/heyi/About_hy.md deleted file mode 100644 index cd57603f..00000000 --- a/contributors/heyi/About_hy.md +++ /dev/null @@ -1,10 +0,0 @@ -# heyi 对本项目的贡献 - -## 贡献1:移除广告信息 - -在项目的早期阶段,为了推广和宣传,大部分 Python 文件的头部添加了一段广告。虽然这在初期可能起到一定的宣传作用,但随着项目的发展,这些冗余的广告信息逐渐显得不必要,并且影响了代码的整洁性和可读性 -##### *heyi* 删除了这些广告,使得代码更整洁、可读 - - ---- -*未完待续...* \ No newline at end of file diff --git a/contributors/hs5057/md_office_demo.py b/contributors/hs5057/md_office_demo.py deleted file mode 100644 index f7227687..00000000 --- a/contributors/hs5057/md_office_demo.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -md-studio + python-office 联动极简示例 -功能流程: -1. 使用 md-studio 将 markdown 文件转为 Word -2. 使用 python-office 读取、修改生成后的 Word 文件 -""" - -# 安装依赖命令 -# pip install python-office md-studio - -import office -# 导入md-studio转换工具 -from md_studio.converter import MdToWord - -def simple_md_office_flow(): - # 1. md 转 word - converter = MdToWord() - converter.convert("demo.md", "output.docx") - - # 2. 使用 python-office 读取生成的word文档 - word = office.Word("output.docx") - content = word.read_text() - print("读取到md转换后的文档内容:", content[:100]) - - # 3. 追加一行文本到word - word.add_paragraph("本文件由 md-studio + python-office 联合处理") - word.save() - print("文档处理完成!") - -if __name__ == "__main__": - simple_md_office_flow() \ No newline at end of file diff --git a/contributors/hs5057/readme.md b/contributors/hs5057/readme.md deleted file mode 100644 index bbeef661..00000000 --- a/contributors/hs5057/readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# md-studio + python-office 联动示例 -配套开源项目:https://github.com/hs5057/md-studio -项目功能:Python 实现 Markdown <-> Word/PDF/HTML 双向文档转换服务 - -本示例演示如何结合 md-studio 与 python-office,完成完整办公文档流转,仅做生态互补演示,不改动项目核心代码。 \ No newline at end of file diff --git a/contributors/hxj04121-lab/test_pdf_add_img_water.py b/contributors/hxj04121-lab/test_pdf_add_img_water.py deleted file mode 100644 index f12a886c..00000000 --- a/contributors/hxj04121-lab/test_pdf_add_img_water.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Regression tests for the PDF image-watermark API wrapper.""" - -import importlib.util -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - - -PDF_API_PATH = Path(__file__).parents[2] / "office" / "api" / "pdf.py" - - -def load_pdf_api(): - """Load the wrapper with a lightweight stand-in for the optional popdf package.""" - popdf = types.ModuleType("popdf") - popdf.add_img_water = mock.Mock() - spec = importlib.util.spec_from_file_location("pdf_api_under_test", PDF_API_PATH) - module = importlib.util.module_from_spec(spec) - - with mock.patch.dict(sys.modules, {"popdf": popdf}): - spec.loader.exec_module(module) - - return module, popdf - - -class TestAddImgWater(unittest.TestCase): - def test_forwards_current_parameters_to_popdf(self): - pdf_api, popdf = load_pdf_api() - - pdf_api.add_img_water("input.pdf", "mark.png", "output.pdf") - - popdf.add_img_water.assert_called_once_with( - pdf_file_in="input.pdf", - pdf_file_mark="mark.png", - pdf_file_out="output.pdf", - ) - - def test_forwards_deprecated_parameter_aliases(self): - pdf_api, popdf = load_pdf_api() - - with self.assertWarnsRegex(DeprecationWarning, "pdf_file_in"): - pdf_api.add_img_water( - pdf_file_in="legacy-input.pdf", - pdf_file_mark="legacy-mark.png", - pdf_file_out="legacy-output.pdf", - ) - - popdf.add_img_water.assert_called_once_with( - pdf_file_in="legacy-input.pdf", - pdf_file_mark="legacy-mark.png", - pdf_file_out="legacy-output.pdf", - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/contributors/marvel2120/WordType.py b/contributors/marvel2120/WordType.py index 87f0325f..2feaa2c6 100644 --- a/contributors/marvel2120/WordType.py +++ b/contributors/marvel2120/WordType.py @@ -7,10 +7,7 @@ # pip install -i https://mirrors.aliyun.com/pypi/simple/ pypiwin32 class MainWord(): - """Word文档处理类,用于将Word文档转换为PDF格式。""" - - def __init__(self) -> None: - """初始化Word应用程序连接。""" + def __init__(self): self.doc = ".doc" self.docx = ".docx" self.pdf = ".popdf" @@ -18,15 +15,7 @@ def __init__(self) -> None: self.word = client.Dispatch("Word.Application") - def file2pdf(self, path: str) -> None: - """将指定目录下的所有Word文档转换为PDF格式。 - - Args: - path (str): 包含Word文档的目录路径 - - Returns: - None - """ + def file2pdf(self, path): # 保存待转换的word文件 word_files = [] @@ -64,16 +53,7 @@ def file2pdf(self, path: str) -> None: for f in remove_files: os.remove(f) - def createpdf(self, word_path: str, pdf_path: str) -> None: - """将单个Word文档转换为PDF格式。 - - Args: - word_path (str): 源Word文档路径 - pdf_path (str): 目标PDF文档路径 - - Returns: - None - """ + def createpdf(self, word_path, pdf_path): print(word_path) try: doc = self.word.Documents.Open(word_path, ReadOnly=1) diff --git a/contributors/old_from_gitee/CNSeniorious000/pdf.py b/contributors/old_from_gitee/ CNSeniorious000/pdf.py similarity index 100% rename from contributors/old_from_gitee/CNSeniorious000/pdf.py rename to contributors/old_from_gitee/ CNSeniorious000/pdf.py diff --git a/contributors/old_from_gitee/han_ying_feng/office/excel.py b/contributors/old_from_gitee/han_ying_feng/office/excel.py index e7cf78ba..cb881de4 100644 --- a/contributors/old_from_gitee/han_ying_feng/office/excel.py +++ b/contributors/old_from_gitee/han_ying_feng/office/excel.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # -*- coding:utf-8 -*- ############################################# diff --git a/contributors/old_from_gitee/han_ying_feng/office/word.py b/contributors/old_from_gitee/han_ying_feng/office/word.py index bb6b82ba..aeb5b1dc 100644 --- a/contributors/old_from_gitee/han_ying_feng/office/word.py +++ b/contributors/old_from_gitee/han_ying_feng/office/word.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # -*- coding:utf-8 -*- ############################################# diff --git a/contributors/rs1973/process_img1.py b/contributors/rs1973/process_img1.py deleted file mode 100644 index bfd7d970..00000000 --- a/contributors/rs1973/process_img1.py +++ /dev/null @@ -1,139 +0,0 @@ -"""" -Creator:rs1973 -E-mail:dingzheng_2023@qq.com/gunshi98@gmail.com -Description:支持输入一个目录或一张图片,修改它(或者整个目录里)的图片尺寸,色彩通道,并决定是否留下图像的 -alpha值,会自动筛选不是图片或不支持的格式 程序为多线程(多进程下使用笔记本测试时cpu过热),但gif合成 -暂时不支持多线程 - -ps:这是我的第一个项目,有很多做得不够好的地方,请多包容 -""" - -import os -import time -from concurrent.futures import ThreadPoolExecutor -from PIL import Image, ImageOps - -def get_img(srcpath=None, sinfile=None): - """筛选目录中的非图片文件,只筛选一层,不读取子目录里的文件""" - - img_lst = [] - not_img = '' - if srcpath: - for dirpath, dirname, filenames in os.walk(srcpath): - if filenames: - for img in filenames: - img = os.path.join(dirpath, img) - if os.path.isfile(img): - if os.path.splitext(img)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".tiff", '.webp'}: - img_lst.append(img) - else: - not_img += f'{img}\n' - else: - print(f'注意: 目录 {dirpath} 中没有图片') - return [] - - if not_img: - print(f'提示: 以下文件/目录不是图片:\n{not_img}') - return img_lst - - if sinfile: - if os.path.splitext(sinfile)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff", '.webp'}: - return [sinfile] - else: - print(f'错误: 文件 {sinfile} 不是图片') - return [] - - -def normal_img(im, input_info: tuple, outpath: str, kind: str, img: str, alpha: bool): - """图像的缩放处理,每一个格式都会用到""" - if input_info: - x, y = input_info - if round(int(x) / im.size[0], 2) == round(int(y) / im.size[1], 2): - real_tuple = (int(x), int(y)) - im = im.resize(real_tuple) - else: - if not alpha: - pad_im = ImageOps.pad(im, (int(x), int(y)), color='#FFFFFF') - else: - pad_im = ImageOps.pad(im, (int(x), int(y)), - color=(0, 0, 0, 0), centering=(0.5, 0.5)) - - im = pad_im - - base_name = os.path.basename(img) - name_only = os.path.splitext(base_name)[0] - save_path = os.path.join(outpath, name_only + kind) - im.save(save_path, format=kind[1:].upper()) - im.close() - - -def gif(filenames=None, outpath=None, duration=300, name='index'): - """合成gif""" - try: - img_lst = [Image.open(i).copy().convert('RGB') for i in filenames] - img_lst[0].save( - os.path.join(outpath, f'{name}.gif'), - append_images=img_lst[1:], - duration=duration, - loop=0, - optimize=True - ) - except ValueError as e: - print(f'错误: 序列中图片大小不一致, {e}') - - -def process_img(outpath=None, input_info=None, kind=None, alpha=None, img=None): - """修改图片中的alpha""" - if kind in ('.png', '.webp', '.bmp'): - with Image.open(img) as im: - im = im.convert('RGBA') - if not alpha: - new_im = im.copy() - new_im.convert('RGB') - alpha_pixel = im.getdata() - write_pixel = [] - for item in alpha_pixel: - r, g, b, a = item - if a == 0: - write_pixel.append((255, 255, 255)) - else: - write_pixel.append((r, g, b)) - new_im.putdata(write_pixel) - im = new_im - normal_img(im, input_info, outpath, kind, img, alpha) - else: - with Image.open(img) as im: - if im.mode == 'RGBA': - im = im.convert('RGB') - normal_img(im, input_info, outpath, kind, img, alpha) - - -def main(srcpath: str = None, outpath: str = None, sinfile: str = None, - img_size: tuple = None, kind: str = '.jpeg', alpha: bool = False, - duration: int = 300, process: int = int(os.cpu_count()//2), name='index'): - """主逻辑函数""" - print('开始处理图片……') - start = time.time() - - filenames = get_img(srcpath, sinfile) - if not filenames: - return - - if kind == '.gif': - print('注意:请确保图像列表中所有图片的大小都一样') - gif(filenames, outpath, duration, name) - else: - with ThreadPoolExecutor(process) as pool: - futures = [pool.submit(process_img, outpath, - img_size, kind, alpha, img) for img in filenames] - for fut in futures: - fut.result() - - end = time.time() - print(f'处理完成, 耗时: {end - start:.2f}s') - -# src = r"C:\Users\rollingstone\OneDrive\Desktop\001" -# out = r"C:\Users\rollingstone\OneDrive\Desktop\s\re" - -# if __name__ == '__main__': -# main(srcpath=src, outpath=out, alpha=False, kind='.gif', name='hello', duration=250) diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md deleted file mode 100644 index 3521029e..00000000 --- a/contributors/rs1973/readme.md +++ /dev/null @@ -1,46 +0,0 @@ -# 批量图片尺寸与通道处理工具 - -**Creator:** rs1973 -**E-mail:** dingzheng_2023@qq.com / gunshi98@gmail.com - -本工具支持对 **单张图片** 或 **整个目录的全部图片** 进行批量处理,包括: - -- 调整图片尺寸 -- 统一色彩通道(可选择去除或保留透明通道 alpha) -- 批量导出到指定目录 -- 支持 `.jpg / .jpeg / .png / .bmp / .tiff / .webp` 格式 -- 支持 GIF 合成(单线程) - -程序内部使用 **多线程** 加速大量图片处理,默认为5线程。 - ---- - -## 功能特点 - -| 功能 | 说明 | -|-----|----------------------------------------------------------------| -| 批量筛选图片 | 自动忽略非图片文件 | -| 多线程处理 | 提升处理速度,默认为5线程 | -| 支持保留 / 去除透明通道 | 当输出格式支持alpha,可以选择保留或丢弃,丢弃时会将原本的alpha像素替换成白色(后续会添加颜色选择选项) | -| 自适应缩放或填充模式 | 保证目标尺寸一致:当目标大小小于原图时,会缩放/拉伸原图,大于且长宽比例与目标大小相同时,则直接缩放,反之则会用白色填充图片 | -| GIF 合成 | 可根据延迟参数调节帧率,默认300ms/帧 | - ---- - -## 基本使用示例 - -```python -from contributors.rs1973.process_img1.py import main - -src = r"C:\path\to\input_dir" -out = r"C:\path\to\output_dir" -size = (1000, 1000) - -main( - srcpath=src, - outpath=out, - img_size=size, - alpha=False, # 是否保留透明通道 - kind='.png', # 输出格式 - duration=300 # GIF 合成时的帧间隔,仅在 kind='.gif' 时使用 -) \ No newline at end of file diff --git a/contributors/sustnf/file.py b/contributors/sustnf/file.py index 48bda5cd..77d3ffe2 100644 --- a/contributors/sustnf/file.py +++ b/contributors/sustnf/file.py @@ -6,27 +6,21 @@ from typing import List class HiddenPrints: - """上下文管理器,用于隐藏print输出。""" - def __enter__(self): - """进入上下文时隐藏输出。""" self._original_stdout = sys.stdout sys.stdout = open(os.devnull, "w") def __exit__(self, exc_type, exc_val, exc_tb): - """退出上下文时恢复输出。""" sys.stdout.close() sys.stdout = self._original_stdout -def screen_file(folder: str, size: int) -> None: - """筛选文件夹中超过指定大小的文件。 - - Args: - folder (str): 文件夹路径 - size (int): 文件大小阈值(单位:MB) - """ +# 判断文件夹中是否有超过固定大小的文件 +# 可对超过具体大小的文件做删除,移动等操作,后续优化 +# folder:文件夹 +# size:大小(M) +def screen_file(folder, size:int): size = size *1024 *1024 res = [] reslist = [] @@ -47,13 +41,8 @@ def screen_file(folder: str, size: int) -> None: -def screen_suffix(folder: str, suffix: List[str]) -> None: - """筛选文件夹中指定后缀的文件。 - - Args: - folder (str): 文件夹路径 - suffix (List[str]): 文件后缀列表 - """ +# 判断文件夹中指定后缀的文件(后缀可多写List类型)['.exe','.txt','.md'] +def screen_suffix(folder, suffix:List): reslist = [] for s in range(len(suffix)): # with HiddenPrints(): @@ -62,14 +51,8 @@ def screen_suffix(folder: str, suffix: List[str]) -> None: print(r) -def one_suffix(folder: str, suf: str, res: list = None) -> None: - """筛选文件夹中指定后缀的文件(单个后缀)。 - - Args: - folder (str): 文件夹路径 - suf (str): 文件后缀 - res (list, optional): 结果列表 - """ +# 判断文件夹中指定后缀的文件 +def one_suffix(folder, suf, res=None): res = [] datanames = os.listdir(folder) for dataname in datanames: diff --git a/contributors/sustnf/md5_verify.py b/contributors/sustnf/md5_verify.py index c69aca6a..fb7faf16 100644 --- a/contributors/sustnf/md5_verify.py +++ b/contributors/sustnf/md5_verify.py @@ -4,13 +4,10 @@ import os -def file_compare(source_file: str, target_file: str) -> None: - """比较两个文件的MD5值。 - - Args: - source_file (str): 源文件路径 - target_file (str): 目标文件路径 - """ +# 文件md5校验 +# source_file:文件1 +# target_file:文件2 +def file_compare(source_file,target_file): s = open(source_file, "br") t = open(target_file, "br") md5_source_file = hashlib.md5(s.read()).hexdigest() diff --git a/contributors/wangpeng/pinyin_gui.py b/contributors/wangpeng/pinyin_gui.py index d280f071..9ea581fa 100644 --- a/contributors/wangpeng/pinyin_gui.py +++ b/contributors/wangpeng/pinyin_gui.py @@ -1,7 +1,7 @@ # -*- coding: UTF-8 -*- ''' -@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:python-office -@读者群 :https://www.python4office.cn/wechat-group/ +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ @学习网站 :https://www.python-office.com @代码日期 :2023/9/26 21:46 @本段代码的视频说明 : @@ -14,15 +14,11 @@ class PinyinConverter(QWidget): - """拼音转换器GUI类,用于将汉字转换为带声调的拼音。""" - - def __init__(self) -> None: - """初始化拼音转换器界面。""" + def __init__(self): super().__init__() self.initUI() - def initUI(self) -> None: - """初始化用户界面组件。""" + def initUI(self): # 创建布局 layout = QVBoxLayout() @@ -62,8 +58,7 @@ def initUI(self) -> None: self.setWindowTitle('拼音转换器') self.setGeometry(300, 300, 300, 200) - def convert(self) -> None: - """将输入的汉字转换为带声调的拼音。""" + def convert(self): # 获取输入文本 input_text = self.input_text.text() @@ -73,14 +68,12 @@ def convert(self) -> None: # 设置输出文本框显示结果 self.output_text.setPlainText(f'带声调的结果:{pinyin_list}') - def copy_output(self) -> None: - """将输出文本复制到剪贴板。""" + def copy_output(self): # 复制输出文本到剪贴板 clipboard = QApplication.clipboard() clipboard.setText(self.output_text.toPlainText()) - def show_about(self) -> None: - """显示关于对话框。""" + def show_about(self): QMessageBox.about(self, '关于', '谨献给一起学习的道友') diff --git a/contributors/yinzeyuan/check_local_dir_image_link_markdown.py b/contributors/yinzeyuan/check_local_dir_image_link_markdown.py index a2854efd..44e62ba3 100644 --- a/contributors/yinzeyuan/check_local_dir_image_link_markdown.py +++ b/contributors/yinzeyuan/check_local_dir_image_link_markdown.py @@ -2,12 +2,11 @@ import pathlib -def check_local_dir_image_link_markdown(markdown_path: str, image_path: str) -> None: - """检查Markdown文件中图片链接与本地图片目录的对应关系。 - - Args: - markdown_path (str): Markdown文件路径 - image_path (str): 本地图片存放路径 +def check_local_dir_image_link_markdown(markdown_path, image_path): + """ + + :param markdown_path: markdown文件路径 + :param image_path: 本地图片存放路径 """ markdown_path = pathlib.Path(markdown_path) image_path = pathlib.Path(image_path) diff --git a/contributors/yinzeyuan/output_file_list_to_excel.py b/contributors/yinzeyuan/output_file_list_to_excel.py index 29749b3f..2a0cf21b 100644 --- a/contributors/yinzeyuan/output_file_list_to_excel.py +++ b/contributors/yinzeyuan/output_file_list_to_excel.py @@ -2,11 +2,9 @@ import openpyxl -def output_file_list_to_excel(dir_path: str) -> None: - """将目录中的文件列表输出到Excel文件。 - - Args: - dir_path (str): 需要生成文件列表的目录路径 +def output_file_list_to_excel(dir_path: str): + """ + :param dir_path: 需要生成文件列表的目录 """ dir_path = pathlib.Path(dir_path).resolve() if dir_path.is_dir(): diff --git "a/demo/PyOfficeRobot/001-\345\217\221\344\270\200\346\235\241\344\277\241\346\201\257.py" "b/demo/PyOfficeRobot/001-\345\217\221\344\270\200\346\235\241\344\277\241\346\201\257.py" new file mode 100644 index 00000000..cd730b9f --- /dev/null +++ "b/demo/PyOfficeRobot/001-\345\217\221\344\270\200\346\235\241\344\277\241\346\201\257.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@Date :2023/2/13 21:19 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1te4y1y7Ro +''' + +# 首先,将PyOfficeRobot模块导入到我们的代码块中。 +import PyOfficeRobot + +PyOfficeRobot.chat.send_message(who='小红书:程序员晚枫', message='你好') +# PyOfficeRobot.chat.send_message(who='每天进步一点点', message='你好') diff --git "a/demo/PyOfficeRobot/002-\345\217\221\346\226\207\344\273\266.py" "b/demo/PyOfficeRobot/002-\345\217\221\346\226\207\344\273\266.py" new file mode 100644 index 00000000..56286343 --- /dev/null +++ "b/demo/PyOfficeRobot/002-\345\217\221\346\226\207\344\273\266.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@Date :2023/2/13 21:19 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1te4y1y7Ro +''' + +import PyOfficeRobot + +# PyOfficeRobot.file.send_file(who='每天进步一点点', file=r'C:\Users\Lenovo\Desktop\temp\0.jpg') +PyOfficeRobot.file.send_file(who='B站:程序员晚枫', file=r'C:\Users\Lenovo\Desktop\temp\0.jpg') diff --git "a/examples/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" "b/demo/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" similarity index 55% rename from "examples/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" rename to "demo/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" index ef2e8bfd..2770163d 100644 --- "a/examples/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" +++ "b/demo/PyOfficeRobot/003-\346\240\271\346\215\256\345\205\263\351\224\256\350\257\215\345\233\236\345\244\215.py" @@ -1,15 +1,18 @@ # -*- coding: UTF-8 -*- -# Author: 程序员晚枫 - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@Date :2023/2/13 21:19 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1m8411b7LZ +''' import PyOfficeRobot - keywords = { "我要报名": "你好,这是报名链接:www.python-office.com", "点赞了吗?": "点了", "关注了吗?": "必须的", "投币了吗?": "三连走起", } -# keywords 中 前面一个引号里的内容是好友发来的消息,后面一个引号里的内容是回复给好友的消息 PyOfficeRobot.chat.chat_by_keywords(who='抖音:程序员晚枫', keywords=keywords) # PyOfficeRobot.chat.chat_by_keywords(who='每天进步一点点', keywords=keywords) diff --git "a/demo/PyOfficeRobot/004-\345\256\232\346\227\266\345\217\221\351\200\201.py" "b/demo/PyOfficeRobot/004-\345\256\232\346\227\266\345\217\221\351\200\201.py" new file mode 100644 index 00000000..27f19e51 --- /dev/null +++ "b/demo/PyOfficeRobot/004-\345\256\232\346\227\266\345\217\221\351\200\201.py" @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@Date :2023/2/13 21:19 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1m8411b7LZ +''' +import PyOfficeRobot + +# PyOfficeRobot.chat.send_message_by_time(who='每天进步一点点', message='你好', time='21:51:55') +PyOfficeRobot.chat.send_message_by_time(who='快手:程序员晚枫', message='你好', time='21:51:55') diff --git "a/examples/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" "b/demo/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" similarity index 52% rename from "examples/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" rename to "demo/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" index baff57c6..14634fc9 100644 --- "a/examples/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" +++ "b/demo/PyOfficeRobot/005-\350\207\252\345\256\232\344\271\211\345\212\237\350\203\275.py" @@ -1,6 +1,11 @@ # -*- coding: UTF-8 -*- -# Author: 程序员晚枫 - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/9 23:22 +@本段代码的视频说明 :https://www.bilibili.com/video/BV14R4y127h6 +''' import PyOfficeRobot import office @@ -10,5 +15,4 @@ "来个密码": office.tools.passwordtools(), } # PyOfficeRobot.chat.chat_by_keywords(who='每天进步一点点', keywords=keywords) -# office.tools.passwordtools() 会生成一个随机的8位数密码 PyOfficeRobot.chat.chat_by_keywords(who='知乎:程序员晚枫', keywords=keywords) \ No newline at end of file diff --git "a/demo/PyOfficeRobot/006-\347\213\254\347\253\213\347\211\210\346\234\254.py" "b/demo/PyOfficeRobot/006-\347\213\254\347\253\213\347\211\210\346\234\254.py" new file mode 100644 index 00000000..2216fe72 --- /dev/null +++ "b/demo/PyOfficeRobot/006-\347\213\254\347\253\213\347\211\210\346\234\254.py" @@ -0,0 +1,20 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/9 23:25 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1SY411y7Uh +''' + +# 原始方式 +import office + +office.wechat.send_message(who='百度一下:程序员晚枫', message='点个star吧') +# office.wechat.send_message(who='每天进步一点点', message='你好') + +# 独立方式 +# import PyOfficeRobot + + +# PyOfficeRobot.chat.send_message(who='百度一下:程序员晚枫', message='点个star吧') diff --git "a/demo/PyOfficeRobot/007-\346\224\266\351\233\206\347\276\244\346\266\210\346\201\257.py" "b/demo/PyOfficeRobot/007-\346\224\266\351\233\206\347\276\244\346\266\210\346\201\257.py" new file mode 100644 index 00000000..2b1f0153 --- /dev/null +++ "b/demo/PyOfficeRobot/007-\346\224\266\351\233\206\347\276\244\346\266\210\346\201\257.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/9 23:28 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1eD4y1g7yZ +''' + +import PyOfficeRobot + +PyOfficeRobot.file.get_group_list() + +# TODO:有BUG:AttributeError: 'NoneType' object has no attribute 'Name' diff --git "a/demo/PyOfficeRobot/008-\345\217\221\346\266\210\346\201\257\346\215\242\350\241\214.py" "b/demo/PyOfficeRobot/008-\345\217\221\346\266\210\346\201\257\346\215\242\350\241\214.py" new file mode 100644 index 00000000..dc4b0be2 --- /dev/null +++ "b/demo/PyOfficeRobot/008-\345\217\221\346\266\210\346\201\257\346\215\242\350\241\214.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/9 23:29 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1Xg4y1s79z +''' + +import PyOfficeRobot + +PyOfficeRobot.chat.send_message(who='每天进步一点点', message='你好' + '{ctrl}{ENTER}' + 'hello') +# PyOfficeRobot.chat.send_message(who='CSDN:程序员晚枫', message='你好' + '{ctrl}{ENTER}' + 'hello') diff --git "a/examples/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" "b/demo/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" similarity index 55% rename from "examples/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" rename to "demo/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" index 89ac9a0d..3aab1fa1 100644 --- "a/examples/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" +++ "b/demo/PyOfficeRobot/009-\346\211\271\351\207\217\345\212\240\345\245\275\345\217\213.py" @@ -1,5 +1,15 @@ # -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/4/27 21:19 +@Description : +''' +""" +批量加好友,1行代码实现 +""" # pip install PyOfficeRobot>=0.1.5 import PyOfficeRobot diff --git "a/demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221.py" "b/demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221.py" new file mode 100644 index 00000000..f277c5fe --- /dev/null +++ "b/demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221.py" @@ -0,0 +1,18 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/4/27 21:20 +@Description : +''' + +""" +定时群发消息 +""" + +# pip +import PyOfficeRobot + +if __name__ == '__main__': + PyOfficeRobot.group.send() diff --git "a/examples/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/content.txt" "b/demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/content.txt" similarity index 100% rename from "examples/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/content.txt" rename to "demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/content.txt" diff --git "a/examples/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/\347\276\244\345\217\221\345\257\271\350\261\241.xls" "b/demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/\347\276\244\345\217\221\345\257\271\350\261\241.xls" similarity index 100% rename from "examples/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/\347\276\244\345\217\221\345\257\271\350\261\241.xls" rename to "demo/PyOfficeRobot/010-\345\256\232\346\227\266\347\276\244\345\217\221\347\232\204\350\265\204\346\226\231/\347\276\244\345\217\221\345\257\271\350\261\241.xls" diff --git a/demo/PyOfficeRobot/011-chat_chatgpt.py b/demo/PyOfficeRobot/011-chat_chatgpt.py new file mode 100644 index 00000000..8859d477 --- /dev/null +++ b/demo/PyOfficeRobot/011-chat_chatgpt.py @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/3/19 18:17 +@Description : +''' +# pip install PyOfficeRobot +import PyOfficeRobot + +# +PyOfficeRobot.chat.chat_by_gpt(who='程序员晚枫', api_key='你的api_key') + +# 24小时、 diff --git "a/demo/PyOfficeRobot/012\343\200\201\346\231\272\350\203\275\350\201\212\345\244\251.py" "b/demo/PyOfficeRobot/012\343\200\201\346\231\272\350\203\275\350\201\212\345\244\251.py" new file mode 100644 index 00000000..1f1cb16f --- /dev/null +++ "b/demo/PyOfficeRobot/012\343\200\201\346\231\272\350\203\275\350\201\212\345\244\251.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/28 21:54 +@本段代码的视频说明 : https://www.bilibili.com/video/BV1394y1e787 +''' + +# pip install PyOfficeRobot +import PyOfficeRobot + +# 1行代码,开始智能聊天 +PyOfficeRobot.chat.chat_robot(who='每天进步一点点') diff --git a/examples/PyOfficeRobot/@AutomationLog.txt b/demo/PyOfficeRobot/@AutomationLog.txt similarity index 100% rename from examples/PyOfficeRobot/@AutomationLog.txt rename to demo/PyOfficeRobot/@AutomationLog.txt diff --git "a/demo/poexcel/Excel\350\275\254PDF.py" "b/demo/poexcel/Excel\350\275\254PDF.py" new file mode 100644 index 00000000..ec6e1494 --- /dev/null +++ "b/demo/poexcel/Excel\350\275\254PDF.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 19:44 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1A84y1N7or/ +''' + +import office + +office.excel.excel2pdf(excel_path=r"D:\test\程序员晚枫.xlsx", + pdf_path=r"D:\test\程序员晚枫.pdf") diff --git a/examples/poexcel/excel/split_excel_by_column.xlsx b/demo/poexcel/excel/split_excel_by_column.xlsx similarity index 100% rename from examples/poexcel/excel/split_excel_by_column.xlsx rename to demo/poexcel/excel/split_excel_by_column.xlsx diff --git a/examples/poexcel/excel/split_excel_by_column_Split_2023-08-06_172552.xlsx b/demo/poexcel/excel/split_excel_by_column_Split_2023-08-06_172552.xlsx similarity index 100% rename from examples/poexcel/excel/split_excel_by_column_Split_2023-08-06_172552.xlsx rename to demo/poexcel/excel/split_excel_by_column_Split_2023-08-06_172552.xlsx diff --git a/examples/poexcel/excel/split_excel_by_column_Split_2023-08-06_172727.xlsx b/demo/poexcel/excel/split_excel_by_column_Split_2023-08-06_172727.xlsx similarity index 100% rename from examples/poexcel/excel/split_excel_by_column_Split_2023-08-06_172727.xlsx rename to demo/poexcel/excel/split_excel_by_column_Split_2023-08-06_172727.xlsx diff --git "a/demo/poexcel/\345\210\233\345\273\272Excel\346\226\207\344\273\266.py" "b/demo/poexcel/\345\210\233\345\273\272Excel\346\226\207\344\273\266.py" new file mode 100644 index 00000000..29e3c30f --- /dev/null +++ "b/demo/poexcel/\345\210\233\345\273\272Excel\346\226\207\344\273\266.py" @@ -0,0 +1,9 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/15 0:30 +@本段代码的视频说明 : +''' + diff --git "a/demo/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" "b/demo/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" new file mode 100644 index 00000000..8e28e2d4 --- /dev/null +++ "b/demo/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/6 20:17 +@本段代码的视频说明 : +''' +import poexcel + +poexcel.merge2sheet(dir_path=r'D:\workplace\code\github\python-office\tests\test_files\excel\merge2sheet', + output_sheet_name=r'platform', output_excel_name=r'./output/merge2sheet') diff --git "a/demo/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" "b/demo/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" new file mode 100644 index 00000000..8a60c115 --- /dev/null +++ "b/demo/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 5:52 +@本段代码的视频说明 : +''' + +import office + +office.excel.merge2excel(dir_path=r'../../contributors/bulabean', output_file='test_merge2excel.xlsx', ) diff --git "a/demo/poexcel/\345\220\214\344\270\200\344\270\252excel\351\207\214\347\232\204\344\270\215\345\220\214sheet\357\274\214\346\213\206\345\210\206\344\270\272\344\270\215\345\220\214\347\232\204excel\346\226\207\344\273\266.py" "b/demo/poexcel/\345\220\214\344\270\200\344\270\252excel\351\207\214\347\232\204\344\270\215\345\220\214sheet\357\274\214\346\213\206\345\210\206\344\270\272\344\270\215\345\220\214\347\232\204excel\346\226\207\344\273\266.py" new file mode 100644 index 00000000..312ddcf8 --- /dev/null +++ "b/demo/poexcel/\345\220\214\344\270\200\344\270\252excel\351\207\214\347\232\204\344\270\215\345\220\214sheet\357\274\214\346\213\206\345\210\206\344\270\272\344\270\215\345\220\214\347\232\204excel\346\226\207\344\273\266.py" @@ -0,0 +1,8 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 5:54 +@本段代码的视频说明 : +''' diff --git "a/demo/poexcel/\346\211\271\351\207\217\346\250\241\346\213\237\346\225\260\346\215\256.py" "b/demo/poexcel/\346\211\271\351\207\217\346\250\241\346\213\237\346\225\260\346\215\256.py" new file mode 100644 index 00000000..8fdd5810 --- /dev/null +++ "b/demo/poexcel/\346\211\271\351\207\217\346\250\241\346\213\237\346\225\260\346\215\256.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/15 0:30 +@本段代码的视频说明 : https://www.bilibili.com/video/BV1wr4y1b7uk/ + 可以模拟的数据类型有:https://mp.weixin.qq.com/s/xVwEjXu58WovgSi4ZTtVQw +''' + +import poexcel + +poexcel.fake2excel(columns=['name', 'text'], rows=20) diff --git "a/demo/poexcel/\346\212\212100\344\270\252Excel\344\270\255\347\254\246\345\220\210\346\235\241\344\273\266\347\232\204\346\225\260\346\215\256\357\274\214\346\261\207\346\200\273\345\210\2601\344\270\252Excel\351\207\214.py" "b/demo/poexcel/\346\212\212100\344\270\252Excel\344\270\255\347\254\246\345\220\210\346\235\241\344\273\266\347\232\204\346\225\260\346\215\256\357\274\214\346\261\207\346\200\273\345\210\2601\344\270\252Excel\351\207\214.py" new file mode 100644 index 00000000..e7f44b70 --- /dev/null +++ "b/demo/poexcel/\346\212\212100\344\270\252Excel\344\270\255\347\254\246\345\220\210\346\235\241\344\273\266\347\232\204\346\225\260\346\215\256\357\274\214\346\261\207\346\200\273\345\210\2601\344\270\252Excel\351\207\214.py" @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/3/25 17:40 +@Description : +''' +import poexcel + +poexcel.query4excel(query_content='程序员晚枫', + query_path=r'必填,放Excel文件的位置') + +# output_path = r'选填,输出查询结果Excel的位置,默认是query_path的位置', +# output_name = '选填,输出的文件名字,默认是:query4excel.xlsx' diff --git "a/demo/poexcel/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\350\257\242Excel.py" "b/demo/poexcel/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\350\257\242Excel.py" new file mode 100644 index 00000000..76497a20 --- /dev/null +++ "b/demo/poexcel/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\350\257\242Excel.py" @@ -0,0 +1,8 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 21:50 +@本段代码的视频说明 : +''' diff --git "a/demo/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" "b/demo/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" new file mode 100644 index 00000000..41872232 --- /dev/null +++ "b/demo/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" @@ -0,0 +1,16 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/6 17:40 +@本段代码的视频说明 : +''' + +import poexcel + +poexcel.split_excel_by_column( + filepath=r'D:\workplace\code\github\python-office\demo\poexcel\excel\split_excel_by_column.xlsx', + column=1, + worksheet_name='platform') + diff --git "a/demo/poexcel/\347\273\237\350\256\241Excel\346\211\223\345\215\260\345\207\272\346\235\245\346\234\211\345\244\232\345\260\221\351\241\265.py" "b/demo/poexcel/\347\273\237\350\256\241Excel\346\211\223\345\215\260\345\207\272\346\235\245\346\234\211\345\244\232\345\260\221\351\241\265.py" new file mode 100644 index 00000000..f265d19c --- /dev/null +++ "b/demo/poexcel/\347\273\237\350\256\241Excel\346\211\223\345\215\260\345\207\272\346\235\245\346\234\211\345\244\232\345\260\221\351\241\265.py" @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 19:43 +@本段代码的文档说明 :https://blog.csdn.net/weixin_42321517/article/details/131218163 +''' + +import poexcel + +# 存放Excel文件的目录 +folder_path = r"D:\程序员晚枫的文件夹\code\github\poexcel\dev" + +poexcel.count4page(folder_path) diff --git "a/examples/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-B\347\253\231.txt" "b/demo/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-B\347\253\231.txt" similarity index 100% rename from "examples/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-B\347\253\231.txt" rename to "demo/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-B\347\253\231.txt" diff --git "a/examples/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-\345\260\217\347\272\242\344\271\246.txt" "b/demo/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-\345\260\217\347\272\242\344\271\246.txt" similarity index 100% rename from "examples/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-\345\260\217\347\272\242\344\271\246.txt" rename to "demo/pofile/test_files/replace4filename/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-\345\260\217\347\272\242\344\271\246.txt" diff --git "a/demo/pofile/\346\211\271\351\207\217\350\216\267\345\217\226\346\226\207\344\273\266\345\210\227\350\241\250.py" "b/demo/pofile/\346\211\271\351\207\217\350\216\267\345\217\226\346\226\207\344\273\266\345\210\227\350\241\250.py" new file mode 100644 index 00000000..5d4198c7 --- /dev/null +++ "b/demo/pofile/\346\211\271\351\207\217\350\216\267\345\217\226\346\226\207\344\273\266\345\210\227\350\241\250.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/20 0:05 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1ua4y1M7ya/ +''' + +# pip install pofile +import pofile + +files_list = pofile.get_files(path=r'D:\workplace\code\github\pofile\tests', name='pdf') +print(files_list) diff --git "a/demo/pofile/\346\211\271\351\207\217\351\207\215\345\221\275\345\220\215.py" "b/demo/pofile/\346\211\271\351\207\217\351\207\215\345\221\275\345\220\215.py" new file mode 100644 index 00000000..6dcc828c --- /dev/null +++ "b/demo/pofile/\346\211\271\351\207\217\351\207\215\345\221\275\345\220\215.py" @@ -0,0 +1,16 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/12 23:52 +@本段代码的视频说明 :https://www.bilibili.com/video/BV12r4y187Yj/ +''' + +import office + +office.file.replace4filename(path=r'./test_files/replace4filename', del_content='程序员晚枫') + +import pofile + +pofile.replace4filename(path=r'./test_files/replace4filename', del_content='程序员晚枫') diff --git "a/demo/pofile/\346\226\260\345\273\272\346\226\207\344\273\266\345\244\271.py" "b/demo/pofile/\346\226\260\345\273\272\346\226\207\344\273\266\345\244\271.py" new file mode 100644 index 00000000..12117e87 --- /dev/null +++ "b/demo/pofile/\346\226\260\345\273\272\346\226\207\344\273\266\345\244\271.py" @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/20 0:06 +@本段代码的视频说明 : +''' +import pofile + +path = r'd://程序员晚枫-新文件夹' +pofile.mkdir((path)) diff --git "a/demo/pofile/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\346\211\276\346\226\207\344\273\266.py" "b/demo/pofile/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\346\211\276\346\226\207\344\273\266.py" new file mode 100644 index 00000000..0c273bcf --- /dev/null +++ "b/demo/pofile/\346\240\271\346\215\256\345\206\205\345\256\271\357\274\214\346\237\245\346\211\276\346\226\207\344\273\266.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/15 0:44 +@本段代码的视频说明 : +''' + +# 导入这个库:python-office,简写为office +import search4file + +# 1行代码,实现 +search4file.search_by_content(r'你的文件夹,例如:d:\\程序员晚枫的文件夹' , content="你需要查找的文件里面的内容,例如:所有平台都叫-程序员晚枫") \ No newline at end of file diff --git "a/demo/pofile/\346\243\200\346\237\245\345\220\216\347\274\200\345\220\215.py" "b/demo/pofile/\346\243\200\346\237\245\345\220\216\347\274\200\345\220\215.py" new file mode 100644 index 00000000..141ba38a --- /dev/null +++ "b/demo/pofile/\346\243\200\346\237\245\345\220\216\347\274\200\345\220\215.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/9 22:27 +@本段代码的视频说明 : +''' + +import pofile + +is_valid = pofile.check_suffix(file_name='程序员晚枫.pdf',suffix_list=['pdf']) +print(is_valid) diff --git "a/demo/pofile/\350\207\252\345\212\250\346\225\264\347\220\206\346\226\207\344\273\266\345\244\271.py" "b/demo/pofile/\350\207\252\345\212\250\346\225\264\347\220\206\346\226\207\344\273\266\345\244\271.py" new file mode 100644 index 00000000..d8754fe0 --- /dev/null +++ "b/demo/pofile/\350\207\252\345\212\250\346\225\264\347\220\206\346\226\207\344\273\266\345\244\271.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/20 0:04 +@本段代码的视频说明 :https://mp.weixin.qq.com/s/AVFttFz-IjZD1Ra3K-580A +''' + + +import office + +path = 'd://程序员晚枫需要整理的文件夹//' +office.file.group_by_name(path) \ No newline at end of file diff --git "a/demo/pofinance/1\343\200\201\345\215\225\346\254\241\345\201\232T.py" "b/demo/pofinance/1\343\200\201\345\215\225\346\254\241\345\201\232T.py" new file mode 100644 index 00000000..cc6d7e03 --- /dev/null +++ "b/demo/pofinance/1\343\200\201\345\215\225\346\254\241\345\201\232T.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/28 11:45 +@本段代码的视频说明 : +''' + +import pofinance + +print(pofinance.t0(11.06, 11.23, 500)) +print(pofinance.t0(11.06, 35.57, 2000)) +print(pofinance.t0(14, 14.5, 300)) diff --git "a/demo/pohan/1\343\200\201\347\273\231\345\217\244\350\257\227\351\205\215\346\213\274\351\237\263.py" "b/demo/pohan/1\343\200\201\347\273\231\345\217\244\350\257\227\351\205\215\346\213\274\351\237\263.py" new file mode 100644 index 00000000..92727858 --- /dev/null +++ "b/demo/pohan/1\343\200\201\347\273\231\345\217\244\350\257\227\351\205\215\346\213\274\351\237\263.py" @@ -0,0 +1,26 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/30 2:59 +@本段代码的视频说明 : +''' + +# pip install pohan +import pohan +from pohan.pinyin.pinyin import Style + +line1 = "床前明月光" + +# 不带声调的 +pinyin_list = pohan.pinyin.han2pinyin(line1, style=Style.NORMAL) +print(f'不带声调的结果:{pinyin_list}') + +# 带声调的 +pinyin_list = pohan.pinyin.han2pinyin(line1, style=Style.TONE) +print(f'带声调的结果:{pinyin_list}') + +# 带数字声调的 +pinyin_list = pohan.pinyin.han2pinyin(line1, style=Style.TONE3) +print(f'带数字声调的结果:{pinyin_list}') diff --git "a/examples/poimage/test_files/add_watermark/mark_img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" "b/demo/poimage/test_files/add_watermark/mark_img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" similarity index 100% rename from "examples/poimage/test_files/add_watermark/mark_img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" rename to "demo/poimage/test_files/add_watermark/mark_img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" diff --git "a/examples/poimage/test_files/add_watermark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" "b/demo/poimage/test_files/add_watermark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" similarity index 100% rename from "examples/poimage/test_files/add_watermark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" rename to "demo/poimage/test_files/add_watermark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" diff --git a/examples/poimage/test_files/del_watermark/del_watermark.jpg b/demo/poimage/test_files/del_watermark/del_watermark.jpg similarity index 100% rename from examples/poimage/test_files/del_watermark/del_watermark.jpg rename to demo/poimage/test_files/del_watermark/del_watermark.jpg diff --git a/examples/poimage/test_files/del_watermark/img.png b/demo/poimage/test_files/del_watermark/img.png similarity index 100% rename from examples/poimage/test_files/del_watermark/img.png rename to demo/poimage/test_files/del_watermark/img.png diff --git "a/examples/poimage/test_files/\344\270\213\350\275\275\345\233\276\347\211\207/B\347\253\231\357\274\232\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.jpg" "b/demo/poimage/test_files/\344\270\213\350\275\275\345\233\276\347\211\207/B\347\253\231\357\274\232\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.jpg" similarity index 100% rename from "examples/poimage/test_files/\344\270\213\350\275\275\345\233\276\347\211\207/B\347\253\231\357\274\232\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.jpg" rename to "demo/poimage/test_files/\344\270\213\350\275\275\345\233\276\347\211\207/B\347\253\231\357\274\232\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.jpg" diff --git "a/demo/poimage/\344\270\213\350\275\275\345\233\276\347\211\207.py" "b/demo/poimage/\344\270\213\350\275\275\345\233\276\347\211\207.py" new file mode 100644 index 00000000..95999507 --- /dev/null +++ "b/demo/poimage/\344\270\213\350\275\275\345\233\276\347\211\207.py" @@ -0,0 +1,20 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/9 22:30 +@本段代码的视频说明 : +''' + +# 导入这个库:python-office,简写为office +import office + +office.image.down4img( + url='https://python-office-1300615378.cos.ap-chongqing.myqcloud.com/icon2.jpg', + output_name='./test_files/下载图片/B站:程序员晚枫', + type='jpg') +# 参数说明: +# url:你要下载的图片链接 +# output_name:下载后的图片名称,可以不填,默认:down4img +# type:下载后的图片类型,可以不填,默认:jpg diff --git "a/demo/poimage/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.py" "b/demo/poimage/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.py" new file mode 100644 index 00000000..074c8265 --- /dev/null +++ "b/demo/poimage/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/20 0:08 +@本段代码的视频说明 : +''' + +import office + +office.image.add_watermark(file='./test_files/add_watermark/程序员晚枫-2.jpg', + mark='公众号:程序员晚枫', + output_path=r'./test_files/add_watermark/mark_img') diff --git "a/examples/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" "b/demo/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" similarity index 60% rename from "examples/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" rename to "demo/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" index e2147597..2f63e7f5 100644 --- "a/examples/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" +++ "b/demo/poimage/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.py" @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/9 22:36 +@本段代码的视频说明 : +''' # pip install poimage,可以使用清华大学的仓库下载:https://www.bilibili.com/video/BV1SM411y7vw import poimage diff --git "a/demo/poimage/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.py" "b/demo/poimage/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.py" new file mode 100644 index 00000000..4a849cfb --- /dev/null +++ "b/demo/poimage/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.py" @@ -0,0 +1,11 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/9 22:48 +@本段代码的视频说明 : +''' +import poimage + +poimage.txt2wordcloud() diff --git a/examples/poimage_demo/compress_image.py b/demo/poimage_demo/compress_image.py similarity index 53% rename from examples/poimage_demo/compress_image.py rename to demo/poimage_demo/compress_image.py index 788d62f3..1b1498d6 100644 --- a/examples/poimage_demo/compress_image.py +++ b/demo/poimage_demo/compress_image.py @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/7/3 23:46 +@Description : +''' import office office.image.compress_image(input_file=r'D:\workplace\code\github\poimage\tests\头像.jpg', diff --git "a/examples/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" "b/demo/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" similarity index 68% rename from "examples/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" rename to "demo/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" index 900633e0..7f9de32a 100644 --- "a/examples/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" +++ "b/demo/poocr/\350\257\206\345\210\253\351\223\266\350\241\214\345\215\241.py" @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/26 0:02 +@本段代码的视频说明 : +''' # pip install poocr import poocr diff --git "a/examples/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" "b/demo/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" similarity index 68% rename from "examples/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" rename to "demo/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" index 8fb4f4de..65fecd82 100644 --- "a/examples/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" +++ "b/demo/poocr/\351\200\232\347\224\250\346\226\207\345\255\227\350\257\206\345\210\253.py" @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/25 22:52 +@本段代码的视频说明 : +''' # pip install poocr import poocr diff --git "a/demo/popdf/PDF\345\212\240\345\257\206.py" "b/demo/popdf/PDF\345\212\240\345\257\206.py" new file mode 100644 index 00000000..675a74ba --- /dev/null +++ "b/demo/popdf/PDF\345\212\240\345\257\206.py" @@ -0,0 +1,18 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:05 +@本段代码的视频说明 : +''' + +# 导入这个库 +import office + +# PDF加密:填写你的文件位置和密码 +office.pdf.encrypt4pdf(path='./test_files/encrypt4pdf/程序员晚枫(作品合集).pdf', password='你想添加的密码') + +# 参数说明: +# path:你的文件位置,例如:D:\work\参考.pdf +# password:你的密码,可以随意设置,不能为空 \ No newline at end of file diff --git "a/demo/popdf/PDF\345\212\240\346\260\264\345\215\260.py" "b/demo/popdf/PDF\345\212\240\346\260\264\345\215\260.py" new file mode 100644 index 00000000..f15f2d19 --- /dev/null +++ "b/demo/popdf/PDF\345\212\240\346\260\264\345\215\260.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/17 22:37 +@本段代码的视频说明 : +''' + +import office + +office.pdf.add_mark(pdf_file=r'./test_files/add_mark/程序员晚枫(没加水印).pdf', mark_str='程序员晚枫', + output_path=r'./test_files/add_mark/output', output_file_name='程序员晚枫(加了水印).pdf') diff --git "a/demo/popdf/PDF\350\247\243\345\257\206.py" "b/demo/popdf/PDF\350\247\243\345\257\206.py" new file mode 100644 index 00000000..9d7b52f7 --- /dev/null +++ "b/demo/popdf/PDF\350\247\243\345\257\206.py" @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:07 +@本段代码的视频说明 : +''' +# 导入这个库:python-office,简写为:office +import office + +# PDF解密:填写你的文件位置和密码 +office.pdf.decrypt4pdf(path='你的加密文件.pdf', password='该文件的密码') \ No newline at end of file diff --git "a/demo/popdf/TXT\350\275\254PDF.py" "b/demo/popdf/TXT\350\275\254PDF.py" new file mode 100644 index 00000000..6723da07 --- /dev/null +++ "b/demo/popdf/TXT\350\275\254PDF.py" @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:01 +@本段代码的视频说明 : +''' + +import office + +office.pdf.txt2pdf(path=r'./test_files/txt2pdf/程序员晚枫.txt', res_pdf='txt2pdf.popdf', output_path=r'./test_files/txt2pdf/output') diff --git a/demo/popdf/pdf_demo.py b/demo/popdf/pdf_demo.py new file mode 100644 index 00000000..2f01454b --- /dev/null +++ b/demo/popdf/pdf_demo.py @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/3/24 23:05 +@Description : +''' +import office + +office.pdf.add_watermark_by_parameters(pdf_file=r'D:\workplace\code\github\popdf\tests\test_files\pdf\in.popdf', + mark_str='python-office') diff --git "a/demo/popdf/pdf\350\275\254word.py" "b/demo/popdf/pdf\350\275\254word.py" new file mode 100644 index 00000000..3f959362 --- /dev/null +++ "b/demo/popdf/pdf\350\275\254word.py" @@ -0,0 +1,20 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/15 0:40 +@本段代码的视频说明 : +''' + +# pip install python-office +import office # 导入第三方库 + +office.pdf.pdf2docx(file_path=r'D:\workplace\code\github\python-office\demo\popdf\test_files\pdf2docx\程序员晚枫.pdf', + output_path=r'D:\download') +# 上面这种是Windows用户 +# 尊贵的Mac和Linux用户 +# pip install popdf +# import popdf +# popdf.pdf2docx(file_path=r'D:\workplace\code\github\python-office\demo\popdf\test_files\pdf2docx\程序员晚枫.pdf', +# output_path=r'./test_files/pdf2docx/output') diff --git "a/examples/popdf/pdf\350\275\254\345\233\276\347\211\207.py" "b/demo/popdf/pdf\350\275\254\345\233\276\347\211\207.py" similarity index 56% rename from "examples/popdf/pdf\350\275\254\345\233\276\347\211\207.py" rename to "demo/popdf/pdf\350\275\254\345\233\276\347\211\207.py" index ca1f192b..7a3a63f2 100644 --- "a/examples/popdf/pdf\350\275\254\345\233\276\347\211\207.py" +++ "b/demo/popdf/pdf\350\275\254\345\233\276\347\211\207.py" @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:09 +@本段代码的视频说明 : +''' # 导入这个库:python-office,简写为office import office diff --git a/examples/popdf/test_files/add_mark/32012356985422-watermark.pdf b/demo/popdf/test_files/add_mark/32012356985422-watermark.pdf similarity index 100% rename from examples/popdf/test_files/add_mark/32012356985422-watermark.pdf rename to demo/popdf/test_files/add_mark/32012356985422-watermark.pdf diff --git "a/examples/popdf/test_files/add_mark/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\345\212\240\344\272\206\346\260\264\345\215\260\357\274\211.pdf" "b/demo/popdf/test_files/add_mark/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\345\212\240\344\272\206\346\260\264\345\215\260\357\274\211.pdf" similarity index 100% rename from "examples/popdf/test_files/add_mark/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\345\212\240\344\272\206\346\260\264\345\215\260\357\274\211.pdf" rename to "demo/popdf/test_files/add_mark/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\345\212\240\344\272\206\346\260\264\345\215\260\357\274\211.pdf" diff --git "a/examples/popdf/test_files/add_mark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\346\262\241\345\212\240\346\260\264\345\215\260\357\274\211.pdf" "b/demo/popdf/test_files/add_mark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\346\262\241\345\212\240\346\260\264\345\215\260\357\274\211.pdf" similarity index 100% rename from "examples/popdf/test_files/add_mark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\346\262\241\345\212\240\346\260\264\345\215\260\357\274\211.pdf" rename to "demo/popdf/test_files/add_mark/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\346\262\241\345\212\240\346\260\264\345\215\260\357\274\211.pdf" diff --git "a/examples/popdf/test_files/decrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" "b/demo/popdf/test_files/decrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" similarity index 100% rename from "examples/popdf/test_files/decrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" rename to "demo/popdf/test_files/decrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" diff --git "a/examples/popdf/test_files/encrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" "b/demo/popdf/test_files/encrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" similarity index 100% rename from "examples/popdf/test_files/encrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" rename to "demo/popdf/test_files/encrypt4pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253\357\274\210\344\275\234\345\223\201\345\220\210\351\233\206\357\274\211.pdf" diff --git "a/examples/popdf/test_files/pdf2docx/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" "b/demo/popdf/test_files/pdf2docx/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" similarity index 100% rename from "examples/popdf/test_files/pdf2docx/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" rename to "demo/popdf/test_files/pdf2docx/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" diff --git "a/examples/popdf/test_files/pdf2docx/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" "b/demo/popdf/test_files/pdf2docx/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" similarity index 100% rename from "examples/popdf/test_files/pdf2docx/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" rename to "demo/popdf/test_files/pdf2docx/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" diff --git "a/examples/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" "b/demo/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" similarity index 74% rename from "examples/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" rename to "demo/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" index fa2606b7..3ed91bca 100644 --- "a/examples/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" +++ "b/demo/popdf/test_files/txt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.txt" @@ -8,4 +8,4 @@ B站:程序员晚枫 个人网站:www.python-office.com -技术答疑群:https://www.python4office.cn/wechat-group/ \ No newline at end of file +技术答疑群:https://mp.weixin.qq.com/s/NN2pX2bQPpczOeGF4ARNtw \ No newline at end of file diff --git "a/demo/popdf/\345\220\210\345\271\266PDF.py" "b/demo/popdf/\345\220\210\345\271\266PDF.py" new file mode 100644 index 00000000..bcae6bf0 --- /dev/null +++ "b/demo/popdf/\345\220\210\345\271\266PDF.py" @@ -0,0 +1,17 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:08 +@本段代码的视频说明 : +''' +# 导入这个库:python-office,简写为office +import office + +#一行代码,合并pdf +office.pdf.merge2pdf(one_by_one=['程序员晚枫.pdf', '一键三连.pdf'], output='走起.pdf') + +#参数作用: +# one_by_one = 是个列表,里面是2个pdf文件,合并后,a在前面,b在后面 +# output = 合并后的pdf名字,不能为空 \ No newline at end of file diff --git a/demo/poppt/merge4ppt.py b/demo/poppt/merge4ppt.py new file mode 100644 index 00000000..9b1baa0e --- /dev/null +++ b/demo/poppt/merge4ppt.py @@ -0,0 +1,19 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/5/25 23:34 +@Description : +''' + +# 集成使用 +import office + +input_path = r"./test_files/merge4ppt" +office.ppt.merge4ppt(input_path) + +# 独立使用 +# import poppt +# +# poppt.merge4ppt(input_path, output_path=r'./output') diff --git a/examples/poppt/ppt2img.py b/demo/poppt/ppt2img.py similarity index 67% rename from examples/poppt/ppt2img.py rename to demo/poppt/ppt2img.py index 8fb85e6f..550a30d5 100644 --- a/examples/poppt/ppt2img.py +++ b/demo/poppt/ppt2img.py @@ -1,5 +1,11 @@ # -*- coding: UTF-8 -*- - +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 23:12 +@本段代码的视频说明 : +''' # pip install python-office import office diff --git a/demo/poppt/ppt2pdf.py b/demo/poppt/ppt2pdf.py new file mode 100644 index 00000000..0b40e96e --- /dev/null +++ b/demo/poppt/ppt2pdf.py @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/18 22:45 +@本段代码的视频说明 :https://www.bilibili.com/video/BV17Y411c792 +''' + +# 导入库:python-office,简写为:office +import office + +# 填入你的ppt目录 +office.ppt.ppt2pdf(path=r'./test_files/ppt2pdf/程序员晚枫.pptx',output_path=r'./test_files/ppt2pdf/output') diff --git "a/examples/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-1.pptx" "b/demo/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-1.pptx" similarity index 100% rename from "examples/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-1.pptx" rename to "demo/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-1.pptx" diff --git "a/examples/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" "b/demo/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" similarity index 100% rename from "examples/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" rename to "demo/poppt/test_files/merge4ppt/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" diff --git "a/examples/poppt/test_files/ppt2img/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" "b/demo/poppt/test_files/ppt2img/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" similarity index 100% rename from "examples/poppt/test_files/ppt2img/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" rename to "demo/poppt/test_files/ppt2img/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.jpg" diff --git "a/examples/poppt/test_files/ppt2img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" "b/demo/poppt/test_files/ppt2img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" similarity index 100% rename from "examples/poppt/test_files/ppt2img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" rename to "demo/poppt/test_files/ppt2img/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253-2.pptx" diff --git "a/examples/poppt/test_files/ppt2pdf/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" "b/demo/poppt/test_files/ppt2pdf/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" similarity index 100% rename from "examples/poppt/test_files/ppt2pdf/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" rename to "demo/poppt/test_files/ppt2pdf/output/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" diff --git "a/examples/poppt/test_files/ppt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pptx" "b/demo/poppt/test_files/ppt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pptx" similarity index 100% rename from "examples/poppt/test_files/ppt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pptx" rename to "demo/poppt/test_files/ppt2pdf/\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pptx" diff --git a/demo/poprogress/simple.py b/demo/poprogress/simple.py new file mode 100644 index 00000000..8c76d5c1 --- /dev/null +++ b/demo/poprogress/simple.py @@ -0,0 +1,13 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫 +@微信 :CoderWanFeng : https://mp.weixin.qq.com/s/8x7c9qiAneTsDJq9JnWLgA +@个人网站 :www.python-office.com +@Date :2023/3/25 17:38 +@Description : +''' + +from poprogress import simple_progress + +for i in simple_progress(range(10000000), desc='当前进度'): + pass diff --git a/demo/porobot/chat.py b/demo/porobot/chat.py new file mode 100644 index 00000000..b0e52b69 --- /dev/null +++ b/demo/porobot/chat.py @@ -0,0 +1,12 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/30 2:57 +@本段代码的视频说明 : +''' + +import porobot + +print(porobot.normal.chat("写首古诗")) diff --git a/demo/povideo/mark2video.py b/demo/povideo/mark2video.py new file mode 100644 index 00000000..dd697a36 --- /dev/null +++ b/demo/povideo/mark2video.py @@ -0,0 +1,11 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/28 0:48 +@本段代码的视频说明 : +''' +import office + +office.video.mark2video(video_path=r'D:\download\baiduyun\图片添加水印.mp4', output_path=r'D:\download\baiduyun\out') diff --git "a/demo/poword/doc\345\222\214docx\344\272\222\350\275\254.py" "b/demo/poword/doc\345\222\214docx\344\272\222\350\275\254.py" new file mode 100644 index 00000000..bb114b0a --- /dev/null +++ "b/demo/poword/doc\345\222\214docx\344\272\222\350\275\254.py" @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 5:41 +@本段代码的视频说明 :https://www.bilibili.com/video/BV1so4y1H7rj +''' + +# pip install python-office 一定要成功哦~ +import office + +office.word.docx2doc(input_path, output_path) + +office.word.doc2docx(input_path, output_path) diff --git "a/examples/poword/test_files/docx2pdf/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" "b/demo/poword/test_files/docx2pdf/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" similarity index 100% rename from "examples/poword/test_files/docx2pdf/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" rename to "demo/poword/test_files/docx2pdf/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" diff --git "a/examples/poword/test_files/docx2pdf/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" "b/demo/poword/test_files/docx2pdf/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" similarity index 100% rename from "examples/poword/test_files/docx2pdf/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" rename to "demo/poword/test_files/docx2pdf/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" diff --git "a/examples/poword/test_files/docx2pdf/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" "b/demo/poword/test_files/docx2pdf/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" similarity index 100% rename from "examples/poword/test_files/docx2pdf/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" rename to "demo/poword/test_files/docx2pdf/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.pdf" diff --git "a/examples/poword/test_files/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" "b/demo/poword/test_files/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" similarity index 100% rename from "examples/poword/test_files/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" rename to "demo/poword/test_files/\345\260\217\347\272\242\344\271\246-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" diff --git "a/examples/poword/test_files/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" "b/demo/poword/test_files/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" similarity index 100% rename from "examples/poword/test_files/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" rename to "demo/poword/test_files/\346\212\226\345\277\253-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" diff --git "a/examples/poword/test_files/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" "b/demo/poword/test_files/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" similarity index 100% rename from "examples/poword/test_files/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" rename to "demo/poword/test_files/\347\237\245\344\271\216-\347\250\213\345\272\217\345\221\230\346\231\232\346\236\253.docx" diff --git "a/demo/poword/word\350\275\254PDF.py" "b/demo/poword/word\350\275\254PDF.py" new file mode 100644 index 00000000..8e5388a9 --- /dev/null +++ "b/demo/poword/word\350\275\254PDF.py" @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/15 0:35 +@本段代码的视频说明 : +''' + +# pip install python-office +import office + +office.word.docx2pdf( + path=r'D:\workplace\code\github\python-office\demo\poword\test_files', + output_path=r'D:\workplace\code\github\python-office\demo\poword\test_files\docx2pdf') diff --git "a/demo/poword/\345\220\210\345\271\266word.py" "b/demo/poword/\345\220\210\345\271\266word.py" new file mode 100644 index 00000000..5b30951e --- /dev/null +++ "b/demo/poword/\345\220\210\345\271\266word.py" @@ -0,0 +1,14 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/7/16 5:38 +@本段代码的视频说明 :https://mp.weixin.qq.com/s/PjQJ3s4Arr872NDfcr-7YA +''' + +# 下载方式:pip install python-office +import office + +office.word.merge4docx(input_path=r'D:\程序员晚枫的文件夹\word-in', + output_path=r'D:\程序员晚枫的文件夹\word-out') \ No newline at end of file diff --git a/examples/pydatav/txt2wordcloud/res.jpg b/demo/pydatav/txt2wordcloud/res.jpg similarity index 100% rename from examples/pydatav/txt2wordcloud/res.jpg rename to demo/pydatav/txt2wordcloud/res.jpg diff --git a/examples/pydatav/txt2wordcloud/test.txt b/demo/pydatav/txt2wordcloud/test.txt similarity index 100% rename from examples/pydatav/txt2wordcloud/test.txt rename to demo/pydatav/txt2wordcloud/test.txt diff --git "a/demo/pydatav/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226-\346\226\207\347\253\240\350\275\254\345\233\276\344\272\221.py" "b/demo/pydatav/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226-\346\226\207\347\253\240\350\275\254\345\233\276\344\272\221.py" new file mode 100644 index 00000000..2079a8fc --- /dev/null +++ "b/demo/pydatav/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226-\346\226\207\347\253\240\350\275\254\345\233\276\344\272\221.py" @@ -0,0 +1,15 @@ +# -*- coding: UTF-8 -*- +''' +@作者 :B站/抖音/微博/小红书/公众号,都叫:程序员晚枫,微信:CoderWanFeng +@读者群 :http://www.python4office.cn/wechat-group/ +@学习网站 :https://www.python-office.com +@代码日期 :2023/8/9 23:25 +@本段代码的视频说明 : +''' +import pydatav + +if __name__ == '__main__': + filename = r'.\txt2wordcloud\test.txt' + color = 'black' + result_file = r'.\txt2wordcloud\res.jpg' + pydatav.image.txt2wordcloud(filename, color, result_file) diff --git a/examples/readme.md b/demo/readme.md similarity index 93% rename from examples/readme.md rename to demo/readme.md index bc4d8e56..69869624 100644 --- a/examples/readme.md +++ b/demo/readme.md @@ -1,15 +1,14 @@ ## 视频教程 -