Repository navigation
refactor(export): replace 3rdparty docx lib with zero-dependency docx writer - #973
Conversation
There was a problem hiding this comment.
Sorry @add-uos, this pull request is too large to review
It changes 28,145 lines. Sourcery can review pull requests with up to 20,000 changed lines.
9d44748 to
9c84646
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 语法正确,逻辑清晰 ✅ 通过 潜在问题: 建议: ['无需修改'] 2. 代码质量 ✅评价: 代码结构清晰,注释完整 ✅ 通过 潜在问题: 建议: ['建议将 CRC-32 查找表改为编译期常量(constexpr 数组)或使用 std::call_once 初始化,消除线程安全隐患'] 3. 代码性能 ✅评价: 性能良好,资源使用合理 ✅ 通过 潜在问题: 建议: ['可将 used 格式列表的收集提取为独立方法(如 collectUsedFormats()),在 saveAs 中调用一次后传给 buildStyles 和 buildSheet 复用'] 4. 代码安全 🔒评价: 存在0个安全漏洞 ✅ 通过
安全漏洞详情: 建议: ['无需安全加固'] 💡 改进建议代码示例// ZipWriter.cpp — 将 CRC-32 查找表改为编译期常量,消除线程安全隐患
// 替换原有的 static bool tableReady + static quint32 table[256] 惰性初始化
namespace ZipDetail {
// 编译期生成 CRC-32 查找表(线程安全,无需运行时初始化)
constexpr quint32 crc32Entry(quint32 i)
{
quint32 c = i;
for (int k = 0; k < 8; ++k)
c = (c & 1) ? (0xEDB88320u ^ (c >> 1)) : (c >> 1);
return c;
}
// C++14 constexpr 不支持循环,可用 Lambda + 编译期展开或直接预生成;
// 此处展示运行时一次性初始化但用 std::call_once 保证线程安全
#include <mutex>
static quint32 table[256];
static std::once_flag tableFlag;
quint32 crc32(const QByteArray &data)
{
std::call_once(tableFlag, [] {
for (quint32 i = 0; i < 256; ++i) {
quint32 c = i;
for (int k = 0; k < 8; ++k)
c = (c & 1) ? (0xEDB88320u ^ (c >> 1)) : (c >> 1);
table[i] = c;
}
});
quint32 crc = 0xFFFFFFFFu;
const unsigned char *p = reinterpret_cast<const unsigned char *>(data.constData());
for (int i = 0; i < data.size(); ++i)
crc = table[(crc ^ p[i]) & 0xFF] ^ (crc >> 8);
return crc ^ 0xFFFFFFFFu;
}
} // namespace ZipDetail本报告由 AI 代码审查工具自动生成 |
|
/forcemerge |
|
This pr force merged! (status: dirty) |
… writer Replace the 3rdparty/docx library (a Qt port of python-docx) with a self-contained DocxWriter, eliminating the bundled template resource and the dependency on Qt private APIs (qzipreader_p/qzipwriter_p). - add shared ZipWriter (STORE zip + CRC-32), refactor XlsxWriter to use it; XlsxDetail keeps only columnName, crc32/escapeXml move to ZipDetail - new DocxWriter builds styles.xml internally (Heading1/Heading2 now actually resolve; the old lib referenced non-existent style names), places pPr before runs per OOXML schema, and appends an empty paragraph after tables - drop assets/template.docx and the whole 3rdparty/docx tree - exportToDoc now returns the real save result instead of always true - add ut_docxwriter (20 cases); unblock previously skipped doc export tests in ut_deviceinfo_export/ut_devicemanager_save; all 2493 tests pass; DocxWriter coverage 98.4%, ZipWriter 97.4% - verified with python-docx and LibreOffice: headings render as Heading 1/2, content and table borders intact 用零依赖 DocxWriter 替换 3rdparty/docx 库(python-docx 的 Qt 移植), 移除内置模板资源与 Qt 私有 API(qzipreader_p/qzipwriter_p)依赖。 - 新增共享 ZipWriter(STORE zip + CRC-32),XlsxWriter 改用之; XlsxDetail 仅保留 columnName,crc32/escapeXml 移至 ZipDetail - DocxWriter 内置 styles.xml(Heading1/Heading2 真实生效,旧库引用 不存在的样式名致标题降级为普通文本),按 OOXML 规范将 pPr 置于 run 之前,表格后补空段落 - 删除 assets/template.docx 与整个 3rdparty/docx 目录 - exportToDoc 返回真实保存结果(旧实现恒返回 true) - 新增 ut_docxwriter(20 例);解除 ut_deviceinfo_export 与 ut_devicemanager_save 中因旧库 SEGV 跳过的 doc 导出测试; 2493 例全过,DocxWriter 覆盖率 98.4%、ZipWriter 97.4% - 经 python-docx 与 LibreOffice 验证:标题正确渲染为 Heading 1/2, 内容与表格边框完整 Log: 用零依赖 DocxWriter 替换三方 docx 库并抽取共享 ZipWriter PMS: TASK-398531 Influence: 导出 Word 报告不再依赖三方库与模板资源,标题样式、表格边框与 OOXML 结构规范化,兼容主流办公软件。
The merge-base changed after approval.
9c84646 to
008b0fc
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: add-uos The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
1 similar comment
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: add-uos The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/forcemerge |
|
This pr force merged! (status: blocked) |
概述 / Summary
移除 3rdparty/docx(python-docx 的 Qt 移植,71 文件约 6.4k 行,依赖模板资源
:/template.docx与 Qt 私有 APIqzipreader_p.h/qzipwriter_p.h),改用自研零依赖 DocxWriter 导出 docx;同时抽取 xlsx/docx 共享的 ZipWriter。Remove 3rdparty/docx (a Qt port of python-docx, 71 files ~6.4k lines, depends on template resource
:/template.docxand Qt private APIsqzipreader_p.h/qzipwriter_p.h) and replace it with a self-implemented zero-dependency DocxWriter; extract a shared ZipWriter for xlsx/docx.实现 / Implementation
src/DeviceManager/ZipWriter:从 XlsxWriter 抽取的共享层(CRC-32 查表法 + STORE 方式 ZIP 容器 +escapeXml),XlsxWriter改用之,XlsxDetail仅保留columnNamesrc/DeviceManager/DocxWriter:不依赖模板,styles.xml内建(Normal/Heading1/Heading2,沿用原模板字体字号与 A4 页面设置),表格内联边框,save返回真实结果addHeading引用不存在的样式名 "1"/"2",标题实际降级为普通文本 → 现在 Heading1/Heading2 真实生效(Word/WPS 导航窗格与目录可识别)pPr写在 run 之后,违反 OOXML schema 顺序 → 修正为 pPr 在前DeviceManager/DeviceInfo/MacroDefinition.h(EXPORT_TO_DOC宏)同步替换,接口形状保持一致(addHeading/addParagraph/addTable/cell/addText)3rdparty/docx整目录与assets/template.docx(appimage.qrc 同步移除)验证 / Verification
ut_docxwriter20 例;解除此前因旧库默认构造 SEGV 而跳过的 7 个 doc 导出用例;全量 2493/2493 通过(与 upstream master 基线一致,存量UT_LogTreeView_drawRow崩溃为基线已有)DocxWriter.cpp98.4%、ZipWriter.cpp97.4%<h1>/<h2>,内容与表格边框完整)、OOXML 结构校验(ZIP 完整性、XML 可解析、pPr 顺序、边框六向齐全)均通过Log
PMS: TASK-398531
删减约 6.4k 行三方代码与模板资源,消除 Qt 私有 API 依赖,修复标题样式失效等 3 处旧缺陷。
Influence
导出 docx 文件仍为 Office Open XML 格式,排版内容与之前一致;标题样式由降级的普通文本恢复为真正的 Heading 1/2。
Summary by Sourcery
Replace the third-party DOCX export stack with a zero-dependency writer and shared ZIP infrastructure while preserving export compatibility and improving document correctness.
New Features:
Bug Fixes:
Enhancements:
Build:
Tests:
Chores: