【QT】 自定义Excel图表系列名称-QXlsx库的扩展实现

扩展QXlsx库以支持自定义Excel图表中的系列名称。

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

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

    // 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 类中添加以下成员:

    // 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 文件中,添加以下方法实现:

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

    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
    }
    

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

// 添加数据系列
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|600x400

自定义导出标题后:

image-20241010162521454|600x400

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计