0 课程表
这个需求可以从日常实例中获得:课程表。
我们常见的课程表有时候是这样的:
大家注意到在左上角的单元格内有一条分割线,把同一个单元格分成两部分。那么在libxlsxwriter中如何实现这一效果呢?
1 官网例程
贴一段官网上的例程代码:
/*
* A simple formatting example that demonstrates how to add diagonal
* cell borders using the libxlsxwriter library.
*
* Copyright 2014-2021, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
/* Create a new workbook and add a worksheet. */
lxw_workbook* workbook = workbook_new("diagonal_border.xlsx");
lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);
/* Add some diagonal border formats. */
lxw_format* format1 = workbook_add_format(workbook);
format_set_diag_type(format1, LXW_DIAGONAL_BORDER_UP);
lxw_format* format2 = workbook_add_format(workbook);
format_set_diag_type(format2, LXW_DIAGONAL_BORDER_DOWN);
lxw_format* format3 = workbook_add_format(workbook);
format_set_diag_type(format3, LXW_DIAGONAL_BORDER_UP_DOWN);
lxw_format* format4 = workbook_add_format(workbook);
format_set_diag_type(format4, LXW_DIAGONAL_BORDER_UP_DOWN);
format_set_diag_border(format4, LXW_BORDER_HAIR);
format_set_diag_color(format4, LXW_COLOR_RED);
worksheet_write_string(worksheet, CELL("B3"), "Text", format1);
worksheet_write_string(worksheet, CELL("B6"), "Text", format2);
worksheet_write_string(worksheet, CELL("B9"), "Text", format3);
worksheet_write_string(worksheet, CELL("B12"), "Text", format4);
workbook_close(workbook);
return 0;
}
这段例程中的关键在于format_set_diag_type(format1, LXW_DIAGONAL_BORDER_UP)
函数的使用,指定了对角线的类型。
类型一共有两种,分别是LXW_DIAGONAL_BORDER_UP
,LXW_DIAGONAL_BORDER_DOWN
.
当然你也可以像这个示例程序中一样,把两种类型的对角线画在同一个单元格之中。
2 课程表实例
小白在官网实例的基础上改造了一下,生成如篇首的那种课程表:
#include "xlsxwriter.h"
#include <iostream>
#include <wchar.h>
#include <windows.h>
#include <vector>
#include <string>
#define TOCN(x) GBKToUTF8(x).data()
using std::string;
using std::vector;
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, lxw_format* sheetformat) {
vector<vector<string>> data =
{
{"", TOCN("星期一"), TOCN("星期二"), TOCN("星期三"), TOCN("星期四"), TOCN("星期五")},
{TOCN("第一节"), TOCN("语文"), TOCN("数学"), TOCN("英语"), TOCN("物理"), TOCN("化学")},
{TOCN("第二节"), TOCN("数学"), TOCN("英语"), TOCN("物理"), TOCN("化学"), TOCN("语文")},
{TOCN("第三节"), TOCN("英语"), TOCN("物理"), TOCN("化学"), TOCN("语文"), TOCN("数学")},
{TOCN("第四节"), TOCN("物理"), TOCN("化学"), TOCN("语文"), TOCN("数学"), TOCN("英语")},
{TOCN("第五节"), TOCN("化学"), TOCN("语文"), TOCN("数学"), TOCN("英语"), TOCN("物理")}
};
int row, col;
for (row = 13; row < 19; row++)
{
for (col = 1; col < 7; col++)
{
worksheet_write_string(worksheet, row, col, data[row - 13][col - 1].data(), sheetformat);
}
}
}
/* 创建一个带有图表的表格文件. */
int main(int argc, char* argv[])
{
lxw_workbook* workbook = workbook_new(GBKToUTF8("斜分割线示例.xlsx").data());
lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);
/* 来自官网例程的部分 */
lxw_format* format1 = workbook_add_format(workbook);
format_set_diag_type(format1, LXW_DIAGONAL_BORDER_UP);
lxw_format* format2 = workbook_add_format(workbook);
format_set_diag_type(format2, LXW_DIAGONAL_BORDER_DOWN);
lxw_format* format3 = workbook_add_format(workbook);
format_set_diag_type(format3, LXW_DIAGONAL_BORDER_UP_DOWN);
lxw_format* format4 = workbook_add_format(workbook);
format_set_diag_type(format4, LXW_DIAGONAL_BORDER_UP_DOWN);
format_set_diag_border(format4, LXW_BORDER_HAIR);
format_set_diag_color(format4, LXW_COLOR_RED);
worksheet_write_string(worksheet, CELL("B3"), "Text", format1);
worksheet_write_string(worksheet, CELL("B6"), "Text", format2);
worksheet_write_string(worksheet, CELL("B9"), "Text", format3);
worksheet_write_string(worksheet, CELL("B12"), "Text", format4);
/* 自己做一个简单的例子 */
lxw_format* format5 = workbook_add_format(workbook);
format_set_diag_type(format5, LXW_DIAGONAL_BORDER_DOWN);
format_set_align(format5, LXW_ALIGN_VERTICAL_DISTRIBUTED);
format_set_align(format5, LXW_ALIGN_LEFT);
format_set_border(format5, LXW_BORDER_THIN);
format_set_font_size(format5, 11);
lxw_format* format6 = workbook_add_format(workbook);
format_set_font_size(format6, 11);
format_set_border(format6, LXW_BORDER_THIN);
format_set_align(format6, LXW_ALIGN_VERTICAL_CENTER);
format_set_align(format6, LXW_ALIGN_CENTER);
write_worksheet_data(worksheet, format6);
// 通过设置行高列宽来控制单元格格式
worksheet_set_row(worksheet, 13, 27.75, NULL);
worksheet_set_column(worksheet, COLS("B:B"), 8.5, NULL);
// 通过空格的控制使上下分离
worksheet_write_string(worksheet, CELL("B14"), TOCN(" 星期\n课程 "), format5);
return workbook_close(workbook);
}
这段代码的关键:
format_set_align(format5, LXW_ALIGN_VERTICAL_DISTRIBUTED)
指定纵向分散对齐;format_set_align(format5, LXW_ALIGN_LEFT)
指定横向左对齐;worksheet_set_row(worksheet, 13, 27.75, NULL)
设定单元格的行高;worksheet_set_column(worksheet, COLS("B:B"), 8.5, NULL)
设定单元格的列宽;- 通过在文本中添加空格和换行符使两个单词文本上下分离并左右对齐;
- 行高和列宽值是根据字体的大小设置的,也是手动尝试的一个过程。
代码的效果:
从libxlsxwriter的作者提供的示例程序来看,单元格斜线的用法主要是用来标注“红叉”或“删除”的意思。这和本文的“课程表”实例对单元格斜线的用法大有不同。
小白也认为这种“课程表”的用法现在也比较少见了。不过作为一种使用技巧,如果有需要的话,还是可以参考一下。
【水平所限,错漏难免。创作不易,轻喷勿骂】