Skip to content

refactor(export): replace QtXlsxWriter with zero-dependency xlsx writer - #972

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:feat/xlsx-zero-dep-writer
Nov 12, 2026
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:feat/xlsx-zero-dep-writer

Conversation

@add-uos

@add-uos add-uos commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

概述 / Summary

移除 3rdparty/QtXlsxWriter(1.2MB,17.5k 行,依赖 Qt 私有 API private/qzipwriter_p.h),改用自研零依赖 XlsxWriter 导出 xlsx。

Remove 3rdparty/QtXlsxWriter (1.2MB, 17.5k lines, depends on Qt private API private/qzipwriter_p.h) and replace it with a self-implemented zero-dependency XlsxWriter.

实现 / Implementation

  • 新增 src/DeviceManager/XlsxWriter:手写 CRC-32(查表法)+ STORE 方式 ZIP 容器 + inlineStr 单元格 + 动态 styles.xml,仅使用 Qt 公开 API
  • 调用点 DeviceInfo / DeviceManager 同步替换,EXPORT_TO_XLSX 宏接口不变
  • 删除 3rdparty/QtXlsxWriter 整目录
  • 单元测试改为「落盘 + 内容校验」模式(sheet1.xml 内容断言),并修复测试暴露的 2 个真实缺陷(样式索引偏移、空表输出)

验证 / Verification

  • 单测:xlsx 相关 25 个用例全过;导出相关过滤 91/91 全过;全量回归与 upstream master 基线一致(存量 UT_LogTreeView_drawRow 崩溃为基线已有)
  • XlsxWriter.cpp 行覆盖率 97.94%
  • 兼容性:Python OOXML 结构校验、openpyxl 回读、LibreOffice 26.8 headless 转 CSV/fods 均通过;WPS 图形界面打开正常

Log

PMS: TASK-398531
删减约 1.2MB 三方代码,消除 Qt 私有 API 依赖。

Influence

导出 xlsx 文件格式与之前保持一致(Office Open XML SpreadsheetML),对用户无感知。

ℹ️ cppcheck 检查项失败为 GitHub API 限制(PR diff 超过 20000 行上限,action 拉取 diff 报 406),非代码问题。已本地用同款 cppcheck 参数验证新增代码 0 error / 0 warning。本 PR 合并后,依赖它的 #973 diff 将收敛至 8.5k 行以内,cppcheck 可恢复正常。

Remove 3rdparty/QtXlsxWriter (which depends on Qt private API) and add
XlsxWriter, a minimal OOXML writer using only public Qt API. Exported
files stay compatible (STORE zip, inlineStr cells, dynamic styles).

移除依赖 Qt 私有 API 的三方库 QtXlsxWriter,新增仅用 Qt 公开 API 的
XlsxWriter 最小 OOXML 写入器。导出文件保持兼容(STORE 不压缩、
inlineStr 单元格、动态样式)。

Log: 移除 QtXlsxWriter,改用自研零依赖 xlsx 写入器
PMS: TASK-398531
Influence: 设备管理器导出 xlsx 功能不变;不再依赖 Qt 私有 API;源码树减小约 1.2MB。

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @add-uos, this pull request is too large to review

It changes 20,763 lines. Sourcery can review pull requests with up to 20,000 changed lines.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 91 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交将第三方 QtXlsxWriter 库替换为零依赖的自研 XlsxWriter 实现,代码结构清晰、 测试覆盖充分、安全防护到位。四维度均通过,无安全漏洞。语法逻辑维度存在 CRC-32 表 静态初始化非线程安全的轻微问题;代码质量维度存在格式收集逻辑重复和 saveAs 方法过长 的问题;代码性能维度存在格式去重 O(n*m) 和重复遍历的小优化空间。总体评价为优秀。

🔍 详细分析

1. 语法逻辑 ✅

评价: 无编译错误,逻辑合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['crc32 函数可改用 C++11 函数级 static 初始化(static const auto table = buildTable();)消除数据竞争,或使用 std::call_once']


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['提取 collectUsedFormats() 私有方法消除 buildStyles 和 buildSheet 中的重复遍历逻辑', '将 saveAs 中的 ZIP 构建逻辑拆分为 buildZipArchive() 等子方法,saveAs 仅负责调用和文件写入']


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['使用 QSet 替代 QList::contains 进行格式去重,降低大表场景下的复杂度', '在 saveAs 中一次遍历收集 used 格式列表,供 buildStyles 和 buildSheet 共享']


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: ['无安全改进建议,代码安全防护到位']


💡 改进建议代码示例

// 建议1: crc32 改用 C++11 magic static 消除数据竞争
namespace XlsxDetail {
quint32 crc32(const QByteArray &data)
{
    // C++11 保证函数级 static 初始化线程安全
    static const struct Crc32Table {
        quint32 table[256];
        Crc32Table() {
            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;
            }
        }
    } table;

    quint32 crc = 0xFFFFFFFFu;
    const unsigned char *p = reinterpret_cast<const unsigned char *>(data.constData());
    for (int i = 0; i < data.size(); ++i)
        crc = table.table[(crc ^ p[i]) & 0xFF] ^ (crc >> 8);
    return crc ^ 0xFFFFFFFFu;
}
}   // namespace XlsxDetail

// 建议2: 提取 collectUsedFormats 消除重复逻辑
QList<XlsxFormat> XlsxWriter::collectUsedFormats() const
{
    QList<XlsxFormat> used;
    for (auto rowIt = m_cells.constBegin(); rowIt != m_cells.constEnd(); ++rowIt) {
        for (auto colIt = rowIt->constBegin(); colIt != rowIt->constEnd(); ++colIt) {
            const XlsxFormat &fmt = colIt->format;
            if (fmt == XlsxFormat())
                continue;
            if (!used.contains(fmt))
                used.append(fmt);
        }
    }
    return used;
}
// buildStyles() 和 buildSheet() 中替换为: const QList<XlsxFormat> used = collectUsedFormats();

本报告由 AI 代码审查工具自动生成

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@add-uos

add-uos commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: unstable)

@deepin-bot
deepin-bot Bot merged commit 09d2202 into linuxdeepin:master Nov 12, 2026
13 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants