libxlsxwriter簇状柱形图绘制

libxlsxwriter的功能覆盖面很大,今天一起来看一下如何用这个库来生成带有簇状柱形图的表格。

1 簇形柱状图

首先来看一下Excel的样例表格,簇状柱形图往往是用来对比若干“系列”的数据在某一时间段内,或某一情境下的差异情况。在商务领域还是非常常见的。

在这里插入图片描述

对于人工智能领域的程序员来说,往往更熟悉的簇状柱形图是核弹厂的性能对比图:
在这里插入图片描述

题外话题外话~

这种图表相信大多数人已经非常熟悉。这里就不多说了。它的几个要素为:

  • 系列
  • 柱形
  • 成簇

2 代码示例及详解

二话不说,先上代码。

#include "xlsxwriter.h"
#include <iostream>
#include <wchar.h>
#include <windows.h>

using std::string;

string GBKToUTF8(const char* strGBK)
{
	int len = MultiByteToWideChar(CP_ACP, 0, strGBK, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, strGBK, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	string strTemp = str;
	if (wstr) delete[] wstr;
	if (str) delete[] str;
	return strTemp;
}

/* 向worksheet中写入一些数据. */
void write_worksheet_data(lxw_worksheet* worksheet) {

    uint8_t data[5][3] = {
        /* 三列数据. */
        {1,   2,   3},
        {2,   4,   6},
        {3,   6,   9},
        {4,   8,  12},
        {5,  10,  15}
    };

    int row, col;

    worksheet_write_string(worksheet, 0, 0, GBKToUTF8("2018年").data(), NULL);                     
	worksheet_write_string(worksheet, 1, 0, GBKToUTF8("2019年").data(), NULL);
	worksheet_write_string(worksheet, 2, 0, GBKToUTF8("2020年").data(), NULL);
    worksheet_write_string(worksheet, 3, 0, GBKToUTF8("2021年").data(), NULL);
    worksheet_write_string(worksheet, 4, 0, GBKToUTF8("2022年").data(), NULL);

    for (row = 0; row < 5; row++)
    {
        for (col = 1; col < 4; col++)
        {
            worksheet_write_number(worksheet, row, col, data[row][col-1], NULL);
        }
    }
}

/* 创建一个带有图表的表格文件. */
int main(int argc, char* argv[]) 
{
    lxw_workbook* workbook = workbook_new(GBKToUTF8("簇状柱形图示例.xlsx").data());                           
    lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);

    /* 向表格中写入一些数据. */
    write_worksheet_data(worksheet);

    /* 创建一个图表对象. */
    lxw_chart* chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);

    // 指定表格,在最简单的例子中我们添加一些数据系列,空的系列种类将默认为1到5
    // 若非空指定数据系列的名称,则可以按照索引列进行指定。
	lxw_chart_series* series1 = chart_add_series(chart, "=Sheet1!$A$1:$A$5", "=Sheet1!$B$1:$B$5");
	lxw_chart_series* series2 = chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
	lxw_chart_series* series3 = chart_add_series(chart, NULL, "=Sheet1!$D$1:$D$5");

    chart_series_set_categories(series1, "Sheet1", 0, 0, 4, 0);
    chart_series_set_categories(series2, "Sheet1", 0, 0, 4, 0);
    chart_series_set_categories(series3, "Sheet1", 0, 0, 4, 0);

    // 给表格添加系列名称
	chart_series_set_name(series1, GBKToUTF8("青菜").data());
	chart_series_set_name(series2, GBKToUTF8("萝卜").data());
	chart_series_set_name(series3, GBKToUTF8("鸡蛋").data());

    // 给表头文字设置格式
    lxw_chart_font font;
    font.bold = LXW_EXPLICIT_FALSE;
    font.color = LXW_COLOR_GREEN;

    chart_title_set_name(chart, GBKToUTF8("年终销售情况").data());
    chart_title_set_name_font(chart, &font);

    // 给坐标轴添加名称
    chart_axis_set_name(chart->x_axis, GBKToUTF8("年份").data());
    chart_axis_set_name(chart->y_axis, GBKToUTF8("万吨").data());

    /* 向worksheet中插入图表. */
    worksheet_insert_chart(worksheet, CELL("B7"), chart);

    return workbook_close(workbook);
}

小白这里的代码还是延续了这个系列文章的一贯风格,即将中文使用添加进了例程之中。以上例程改编自libxlsxwriter官网的例程chart.c。

以上程序生成一个名为簇状柱形图示例.xlsx的表格。最终内容呈现如下图所示:
在这里插入图片描述

重点需要说明的是:

系列,即图中横坐标上的2018年~2022年,有两种方式进行插入

  • chart_add_series(chart, "=Sheet1!$A$1:$A$5", "=Sheet1!$B$1:$B$5");这种方式中第二个参数指定了系列数据的来源是A1到A5单元格;
  • chart_series_set_categories(series1, "Sheet1", 0, 0, 4, 0);这种方式通过坐标指定(0,0)到(0,4)单元格为系列的数据来源。

chart_series_set_name(series1, GBKToUTF8("青菜").data());通过这种方式给系列指定名称。

chart_axis_set_name(chart->x_axis, GBKToUTF8("年份").data());通过这种方式来给坐标轴插入标题;

worksheet_insert_chart(worksheet, CELL("B7"), chart); 通过这种方式来将图表插入到表格中的指定位置(图片的左上角插入到对应的单元格,此例中插入到B7)。

看似简单,实际上,确实也不难。注意消化掉这个例程就好。还有一些其他的表格相关的指定功能这里可能没涉及到,在以后的博客文章中可能慢慢涉及。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值