Back

自定义 Excel 图表系列名称——QXlsx 库的扩展实现

By Ming 十月 10, 2024 Qt

为了添加设置图例标题的功能,我们需要在 Chart 类中添加一个新的方法,并在 ChartPrivate 类中实现相应的功能。以下是修改后的代码:

  1. xlsxchart.h 文件中,在 Chart 类的公共方法部分添加以下声明:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // xlsxchart.h

    // ... (前面的代码保持不变)
    public:
    void addSeries(const CellRange &range,
    AbstractSheet *sheet = nullptr,
    bool headerH = false,
    bool headerV = false,
    bool swapHeaders = false);
    void setChartType(ChartType type);
    void setChartStyle(int id);
    void setAxisTitle(Chart::ChartAxisPos pos, QString axisTitle);
    void setChartTitle(QString strchartTitle);
    void setChartLegend(Chart::ChartAxisPos legendPos, bool overlap = false);
    void setGridlinesEnable(bool majorGridlinesEnable = false, bool minorGridlinesEnable = false);
    void setSeriesName(int index, const QString &name); // 新添加的方法
    // ... (后面的代码保持不变)
  2. xlsxchart_p.h 文件中,在 ChartPrivate 类中添加以下成员:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // xlsxchart_P.h

    // ... (前面的代码保持不变)
    public:
    Chart::ChartType chartType;
    QList<std::shared_ptr<XlsxSeries>> seriesList;
    QList<std::shared_ptr<XlsxAxis>> axisList;
    QMap<XlsxAxis::AxisPos, QString> axisNames;
    QString chartTitle;
    AbstractSheet *sheet;
    Chart::ChartAxisPos legendPos;
    bool legendOverlay;
    bool majorGridlinesEnabled;
    bool minorGridlinesEnabled;

    QString layout; // only for storing a read file

    QMap<int, QString> seriesNames; // 新添加
    // ... (后面的代码保持不变)
  3. xlsxchart.cpp 文件中,添加以下方法实现:

    1
    2
    3
    4
    5
    void Chart::setSeriesName(int index, const QString &name)
    {
    Q_D(Chart);
    d->seriesNames[index] = name;
    }
  4. ChartPrivate::saveXmlSer 方法中,修改保存系列名称的部分。在 writer.writeStartElement(QStringLiteral("c:ser")); 之后添加以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    void ChartPrivate::saveXmlSer(QXmlStreamWriter &writer, XlsxSeries *ser, int id) const
    {
    writer.writeStartElement(QStringLiteral("c:ser"));
    writer.writeEmptyElement(QStringLiteral("c:idx"));
    writer.writeAttribute(QStringLiteral("val"), QString::number(id));
    writer.writeEmptyElement(QStringLiteral("c:order"));
    writer.writeAttribute(QStringLiteral("val"), QString::number(id));

    // 添加自定义系列名称
    if (seriesNames.contains(id)) {
    writer.writeStartElement(QStringLiteral("c:tx"));
    writer.writeStartElement(QStringLiteral("c:v"));
    writer.writeCharacters(seriesNames[id]);
    writer.writeEndElement(); // c:v
    writer.writeEndElement(); // c:tx
    } else if (!ser->headerV_numRef.isEmpty()) {
    writer.writeStartElement(QStringLiteral("c:tx"));
    writer.writeStartElement(QStringLiteral("c:strRef"));
    writer.writeTextElement(QStringLiteral("c:f"), ser->headerV_numRef);
    writer.writeEndElement(); // c:strRef
    writer.writeEndElement(); // c:tx
    }

    // ... (其余代码保持不变)

    writer.writeEndElement(); // c:ser
    }

然后,你可以根据需要设置系列名称为对应的列标题:

1
2
3
4
5
6
7
8
9
10
11
12
// 添加数据系列
for (int col = 2; col < headers.size(); ++col) {
QXlsx::CellRange range(3, col + 1, row - 1, col + 1);
lineChart->addSeries(range, xlsx.currentSheet(), true, false);

// ...

// 设置系列名称为对应的列标题
lineChart->setSeriesName(col - 2, headers[col]);

// ...
}

原始 QXlsx 插入折线图:

image-20241010162436162

自定义导出标题后:

image-20241010162521454

许可协议

本文由 Ming 原创,采用 CC BY-NC-SA 4.0 协议。转载请注明出处。

PERMALINK

https://iming.eu.org/2024/10/10/qt-xlsx-chart/

Comments