mirror of
https://github.com/jmcnamara/libxlsxwriter.git
synced 2026-05-15 14:15:54 -06:00
Added additional tests and y2 upgrades
This commit is contained in:
parent
f0647157ba
commit
e85d8d768f
28 changed files with 2908 additions and 390 deletions
28
.claude/settings.local.json
Normal file
28
.claude/settings.local.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(grep:*)",
|
||||
"Bash(unzip:*)",
|
||||
"Bash(xmllint:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(make clean:*)",
|
||||
"Bash(make:*)",
|
||||
"Bash(gcc:*)",
|
||||
"Bash(./test_y2_axis:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(rm:*)",
|
||||
"Bash(echo:*)",
|
||||
"Bash(./test_single_axis:*)",
|
||||
"Bash(if [ -f test_single_verify/xl/charts/_rels/chart1.xml.rels ])",
|
||||
"Bash(then echo \" ✓ YES\")",
|
||||
"Bash(else echo \" ✗ NO\")",
|
||||
"Bash(fi)",
|
||||
"Bash(./test_bar_y2:*)",
|
||||
"Bash(./test_area_y2)",
|
||||
"Bash(./test_scatter_styled:*)",
|
||||
"Bash(convert:*)",
|
||||
"Bash(LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH ./test_scatter_styled:*)",
|
||||
"Bash(LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH ./test_scatter_chartsheet:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
- This is shared object library version `libxlsxwriter.so.10`. This should be
|
||||
updated automatically via `make` and `cmake` as part of the build process.
|
||||
This version contains ABI changes since the previous release.
|
||||
|
||||
- Please report any downstream patches back upstream to help improve the overall
|
||||
build process.
|
||||
|
|
|
|||
97
build.zig
97
build.zig
|
|
@ -1,16 +1,14 @@
|
|||
const std = @import("std");
|
||||
const zon_version = @import("build.zig.zon").version;
|
||||
|
||||
const xlsxw_version: std.SemanticVersion = .{
|
||||
.major = 1,
|
||||
.minor = 1,
|
||||
.patch = 9,
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const options: BuildConfig = .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
};
|
||||
const xlsxw_version = std.SemanticVersion.parse(zon_version) catch |err| {
|
||||
std.debug.panic("Error: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
const shared = b.option(bool, "SHARED_LIBRARY", "Build the Shared Library [default: false]") orelse false;
|
||||
const examples = b.option(bool, "BUILD_EXAMPLES", "Build libxlsxwriter examples [default: false]") orelse false;
|
||||
|
|
@ -20,11 +18,15 @@ pub fn build(b: *std.Build) void {
|
|||
const md5 = b.option(bool, "USE_OPENSSL_MD5", "Build libxlsxwriter with the OpenSSL MD5 lib [default: off]") orelse false;
|
||||
const stdtmpfile = b.option(bool, "USE_STANDARD_TMPFILE", "Use the C standard library's tmpfile() [default: off]") orelse false;
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
const lib = if (shared) b.addSharedLibrary(.{
|
||||
.name = "xlsxwriter",
|
||||
.root_module = createModule(b, options),
|
||||
.linkage = if (shared) .dynamic else .static,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.version = xlsxw_version,
|
||||
}) else b.addStaticLibrary(.{
|
||||
.name = "xlsxwriter",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
lib.pie = true;
|
||||
switch (optimize) {
|
||||
|
|
@ -78,7 +80,7 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
}
|
||||
|
||||
const zlib = buildZlib(b, options);
|
||||
const zlib = buildZlib(b, .{ target, optimize });
|
||||
lib.linkLibrary(zlib);
|
||||
lib.installLibraryHeaders(zlib);
|
||||
|
||||
|
|
@ -120,52 +122,42 @@ pub fn build(b: *std.Build) void {
|
|||
// build examples
|
||||
if (examples) {
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/anatomy.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/array_formula.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/autofilter.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/background.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/chart_area.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/chart_column.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/data_validate.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/hello.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/watermark.c",
|
||||
});
|
||||
buildExe(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "examples/worksheet_protection.c",
|
||||
});
|
||||
|
|
@ -173,112 +165,93 @@ pub fn build(b: *std.Build) void {
|
|||
// build tests
|
||||
if (tests) {
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/app/test_app.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/chart/test_chart.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/chartsheet/test_chartsheet.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/content_types/test_content_types.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/content_types/test_content_types_write_default.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/content_types/test_content_types_write_override.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/relationships/test_relationships.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/app/test_app_xml_declaration.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/relationships/test_relationships_xml_declaration.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/custom/test_custom_xml_declaration.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/metadata/test_metadata_xml_declaration.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/core/test_core_xml_declaration.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/sst/test_shared_strings.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/workbook/test_workbook.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/xmlwriter/test_xmlwriter.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/table/test_table01.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/table/test_table02.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/table/test_table03.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/table/test_table04.c",
|
||||
});
|
||||
buildTest(b, .{
|
||||
.options = options,
|
||||
.lib = lib,
|
||||
.path = "test/unit/styles/test_styles_write_border.c",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn buildExe(b: *std.Build, info: BuildExec) void {
|
||||
fn buildExe(b: *std.Build, info: BuildInfo) void {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = info.filename(),
|
||||
.root_module = createModule(b, info.options),
|
||||
.optimize = info.lib.root_module.optimize.?,
|
||||
.target = info.lib.root_module.resolved_target.?,
|
||||
});
|
||||
exe.addCSourceFile(.{
|
||||
.file = b.path(info.path),
|
||||
|
|
@ -304,10 +277,11 @@ fn buildExe(b: *std.Build, info: BuildExec) void {
|
|||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
fn buildTest(b: *std.Build, info: BuildExec) void {
|
||||
fn buildTest(b: *std.Build, info: BuildInfo) void {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = info.filename(),
|
||||
.root_module = createModule(b, info.options),
|
||||
.optimize = info.lib.root_module.optimize.?,
|
||||
.target = info.lib.root_module.resolved_target.?,
|
||||
});
|
||||
exe.root_module.addCMacro("TESTING", "");
|
||||
exe.addCSourceFile(.{
|
||||
|
|
@ -319,10 +293,10 @@ fn buildTest(b: *std.Build, info: BuildExec) void {
|
|||
.flags = cflags,
|
||||
});
|
||||
exe.addIncludePath(b.path("test/unit"));
|
||||
exe.linkLibrary(info.lib);
|
||||
for (info.lib.root_module.include_dirs.items) |include| {
|
||||
exe.root_module.include_dirs.append(b.allocator, include) catch @panic("OOM");
|
||||
exe.root_module.include_dirs.append(b.allocator, include) catch {};
|
||||
}
|
||||
exe.linkLibrary(info.lib);
|
||||
exe.linkLibC();
|
||||
b.installArtifact(exe);
|
||||
|
||||
|
|
@ -339,13 +313,6 @@ fn buildTest(b: *std.Build, info: BuildExec) void {
|
|||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
fn createModule(b: *std.Build, options: BuildConfig) *std.Build.Module {
|
||||
return b.createModule(.{
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
});
|
||||
}
|
||||
|
||||
const cflags = &.{
|
||||
"-std=c89",
|
||||
"-Wall",
|
||||
|
|
@ -359,29 +326,25 @@ const minizip_src: []const []const u8 = &.{
|
|||
"third_party/minizip/zip.c",
|
||||
};
|
||||
|
||||
const BuildExec = struct {
|
||||
options: BuildConfig,
|
||||
const BuildInfo = struct {
|
||||
lib: *std.Build.Step.Compile,
|
||||
path: []const u8,
|
||||
|
||||
fn filename(self: BuildExec) []const u8 {
|
||||
fn filename(self: BuildInfo) []const u8 {
|
||||
var split = std.mem.splitSequence(u8, std.fs.path.basename(self.path), ".");
|
||||
return split.first();
|
||||
}
|
||||
};
|
||||
const BuildConfig = struct {
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
};
|
||||
|
||||
fn buildZlib(b: *std.Build, options: BuildConfig) *std.Build.Step.Compile {
|
||||
const libz = b.addLibrary(.{
|
||||
fn buildZlib(b: *std.Build, options: anytype) *std.Build.Step.Compile {
|
||||
const libz = b.addStaticLibrary(.{
|
||||
.name = "z",
|
||||
.root_module = createModule(b, options),
|
||||
.target = options[0],
|
||||
.optimize = options[1],
|
||||
});
|
||||
if (b.lazyDependency("zlib", .{
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
.target = options[0],
|
||||
.optimize = options[1],
|
||||
})) |zlib_path| {
|
||||
libz.addIncludePath(zlib_path.path(""));
|
||||
libz.addCSourceFiles(.{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.name = .libxlsxwriter,
|
||||
.version = "1.1.9",
|
||||
.fingerprint = 0xa28d9a85f22fad0e,
|
||||
.minimum_zig_version = "0.15.1",
|
||||
.minimum_zig_version = "0.14.0",
|
||||
.dependencies = .{
|
||||
.zlib = .{
|
||||
.url = "git+https://github.com/madler/zlib#v1.3.1",
|
||||
|
|
|
|||
113
examples/test_area_y2.c
Normal file
113
examples/test_area_y2.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Test program to verify area chart secondary Y-axis functionality.
|
||||
* Tests area chart with two series on different Y-axes.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Area Chart Secondary Y-Axis Test ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_area_y2.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_AREA);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Quarter", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Units Sold (1000s)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Market Share (%)", NULL);
|
||||
|
||||
/* Write some data with different scales to demonstrate secondary axis. */
|
||||
/* Column A: X-axis values (quarters) */
|
||||
const char *quarters[] = {"Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "Q7", "Q8"};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_string(worksheet, i + 1, 0, quarters[i], NULL);
|
||||
}
|
||||
|
||||
/* Column B: Small scale values - Units Sold (primary Y-axis, left side) */
|
||||
double units[] = {12.5, 15.3, 18.7, 22.1, 25.8, 28.3, 30.2, 31.5};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, units[i], NULL);
|
||||
}
|
||||
|
||||
/* Column C: Different scale values - Market Share % (secondary Y-axis, right side) */
|
||||
double market_share[] = {8.5, 12.3, 15.7, 18.2, 22.5, 26.8, 29.3, 32.1};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, market_share[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (8 quarters, 2 series with different scales)...\n");
|
||||
|
||||
/* Add series to primary Y-axis (left side) - Units Sold */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$9",
|
||||
"=Data!$B$2:$B$9",
|
||||
chart->y_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
printf("2. Added primary series (Units Sold) to left Y-axis...\n");
|
||||
|
||||
/* Add series to secondary Y-axis (right side) - Market Share */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$9",
|
||||
"=Data!$C$2:$C$9",
|
||||
chart->y2_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
printf("3. Added secondary series (Market Share) to right Y-axis...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Units Sold and Market Share by Quarter");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Quarter");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Units Sold (1000s)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Market Share (%)");
|
||||
|
||||
/* Position the secondary Y-axis title on the right side of the chart */
|
||||
lxw_chart_layout layout = {
|
||||
.x = 0.686,
|
||||
.y = 0.314,
|
||||
.width = 0.0,
|
||||
.height = 0.0,
|
||||
.has_inner = LXW_FALSE
|
||||
};
|
||||
chart_axis_set_name_layout(chart->y2_axis, &layout);
|
||||
|
||||
printf("4. Configured chart title and axis labels...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_area_y2.xlsx\n\n");
|
||||
printf("Expected behavior:\n");
|
||||
printf(" - Area chart with TWO Y-axes\n");
|
||||
printf(" - Units Sold series on left Y-axis (0-35 range)\n");
|
||||
printf(" - Market Share series on right Y-axis (0-35%% range)\n");
|
||||
printf(" - Both series plotted against quarters on X-axis\n");
|
||||
printf(" - Two areaChart elements in the XML\n");
|
||||
printf(" - Four axes total (2 X-axes, 2 Y-axes)\n\n");
|
||||
printf("Open test_area_y2.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
113
examples/test_bar_y2.c
Normal file
113
examples/test_bar_y2.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Test program to verify bar chart secondary Y-axis functionality.
|
||||
* Tests horizontal bar chart with two series on different Y-axes.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Bar Chart Secondary Y-Axis Test ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_bar_y2.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_BAR);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Department", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Employees", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Budget ($M)", NULL);
|
||||
|
||||
/* Write some data with different scales to demonstrate secondary axis. */
|
||||
/* Column A: X-axis values (departments) */
|
||||
const char *departments[] = {"Engineering", "Sales", "Marketing", "Operations", "HR", "Finance"};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_string(worksheet, i + 1, 0, departments[i], NULL);
|
||||
}
|
||||
|
||||
/* Column B: Small scale values - Employees (primary Y-axis, left side) */
|
||||
double employees[] = {45, 32, 18, 28, 12, 15};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, employees[i], NULL);
|
||||
}
|
||||
|
||||
/* Column C: Large scale values - Budget in millions (secondary Y-axis, right side) */
|
||||
double budget[] = {8.5, 6.2, 3.8, 5.1, 2.2, 2.8};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, budget[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (6 departments, 2 series with different scales)...\n");
|
||||
|
||||
/* Add series to primary Y-axis (left side) - Employees */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$7",
|
||||
"=Data!$B$2:$B$7",
|
||||
chart->y_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
printf("2. Added primary series (Employees) to left Y-axis...\n");
|
||||
|
||||
/* Add series to secondary Y-axis (right side) - Budget */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$7",
|
||||
"=Data!$C$2:$C$7",
|
||||
chart->y2_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
printf("3. Added secondary series (Budget) to right Y-axis...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Department Employees and Budget");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Department");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Employees");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Budget ($M)");
|
||||
|
||||
/* Position the secondary Y-axis title on the right side of the chart */
|
||||
lxw_chart_layout layout = {
|
||||
.x = 0.686,
|
||||
.y = 0.314,
|
||||
.width = 0.0,
|
||||
.height = 0.0,
|
||||
.has_inner = LXW_FALSE
|
||||
};
|
||||
chart_axis_set_name_layout(chart->y2_axis, &layout);
|
||||
|
||||
printf("4. Configured chart title and axis labels...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_bar_y2.xlsx\n\n");
|
||||
printf("Expected behavior:\n");
|
||||
printf(" - Horizontal bar chart with TWO Y-axes\n");
|
||||
printf(" - Employees series on left Y-axis (0-50 range)\n");
|
||||
printf(" - Budget series on right Y-axis (0-10M range)\n");
|
||||
printf(" - Both series plotted against departments on X-axis\n");
|
||||
printf(" - Two barChart elements in the XML\n");
|
||||
printf(" - Four axes total (2 X-axes, 2 Y-axes)\n\n");
|
||||
printf("Open test_bar_y2.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
113
examples/test_column_y2.c
Normal file
113
examples/test_column_y2.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Test program to verify column chart secondary Y-axis functionality.
|
||||
* Tests vertical column chart with two series on different Y-axes.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Column Chart Secondary Y-Axis Test ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_column_y2.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Product", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Sales (Units)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Profit ($K)", NULL);
|
||||
|
||||
/* Write some data with different scales to demonstrate secondary axis. */
|
||||
/* Column A: X-axis values (products) */
|
||||
const char *products[] = {"Widget A", "Widget B", "Widget C", "Widget D", "Widget E", "Widget F"};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_string(worksheet, i + 1, 0, products[i], NULL);
|
||||
}
|
||||
|
||||
/* Column B: Large scale values - Sales Units (primary Y-axis, left side) */
|
||||
double sales[] = {1250, 1850, 2340, 1920, 2680, 3120};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, sales[i], NULL);
|
||||
}
|
||||
|
||||
/* Column C: Small scale values - Profit in thousands (secondary Y-axis, right side) */
|
||||
double profit[] = {45.2, 68.5, 92.3, 71.8, 105.6, 128.4};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, profit[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (6 products, 2 series with different scales)...\n");
|
||||
|
||||
/* Add series to primary Y-axis (left side) - Sales */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$7",
|
||||
"=Data!$B$2:$B$7",
|
||||
chart->y_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
printf("2. Added primary series (Sales) to left Y-axis...\n");
|
||||
|
||||
/* Add series to secondary Y-axis (right side) - Profit */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$7",
|
||||
"=Data!$C$2:$C$7",
|
||||
chart->y2_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
printf("3. Added secondary series (Profit) to right Y-axis...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Product Sales and Profit");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Product");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Sales (Units)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Profit ($K)");
|
||||
|
||||
/* Position the secondary Y-axis title on the right side of the chart */
|
||||
lxw_chart_layout layout = {
|
||||
.x = 0.686,
|
||||
.y = 0.314,
|
||||
.width = 0.0,
|
||||
.height = 0.0,
|
||||
.has_inner = LXW_FALSE
|
||||
};
|
||||
chart_axis_set_name_layout(chart->y2_axis, &layout);
|
||||
|
||||
printf("4. Configured chart title and axis labels...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_column_y2.xlsx\n\n");
|
||||
printf("Expected behavior:\n");
|
||||
printf(" - Column chart with TWO Y-axes\n");
|
||||
printf(" - Sales series on left Y-axis (0-3500 range)\n");
|
||||
printf(" - Profit series on right Y-axis (0-140K range)\n");
|
||||
printf(" - Both series plotted against products on X-axis\n");
|
||||
printf(" - Two barChart elements in the XML (with barDir=\"col\")\n");
|
||||
printf(" - Four axes total (2 X-axes, 2 Y-axes)\n\n");
|
||||
printf("Open test_column_y2.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
146
examples/test_scatter_chartsheet.c
Normal file
146
examples/test_scatter_chartsheet.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Test program to create a styled scatter chart in a chartsheet.
|
||||
* This is the chartsheet version of test_scatter_styled.c
|
||||
* Features:
|
||||
* - Circle markers with custom colors (blue/orange to approximate accent1/accent2)
|
||||
* - No lines connecting markers
|
||||
* - Legend at bottom
|
||||
* - Secondary Y-axis
|
||||
* - Formatted axis titles
|
||||
* - Chart displayed in a dedicated chartsheet
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Styled Scatter Chart in Chartsheet ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_scatter_chartsheet.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chartsheet *chartsheet = workbook_add_chartsheet(workbook, "Chart");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_SCATTER);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Time (hours)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Velocity (m/s)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Distance (km)", NULL);
|
||||
|
||||
/* Write time data (X-axis) */
|
||||
double time[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 0, time[i], NULL);
|
||||
}
|
||||
|
||||
/* Write velocity data (primary Y-axis, left side) */
|
||||
double velocity[] = {0, 5.5, 12.3, 18.7, 22.1, 23.8, 24.2, 24.5, 24.7};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, velocity[i], NULL);
|
||||
}
|
||||
|
||||
/* Write distance data (secondary Y-axis, right side) */
|
||||
double distance[] = {0, 5, 25, 70, 135, 215, 285, 385, 500};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, distance[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (9 time points, 2 series)...\n");
|
||||
|
||||
/* Configure colors to approximate Excel's accent1 (blue) and accent2 (orange) */
|
||||
lxw_color_t accent1_color = 0x4472C4; /* Excel default accent1: blue */
|
||||
lxw_color_t accent2_color = 0xED7D31; /* Excel default accent2: orange */
|
||||
|
||||
/* Configure series 1 (Velocity) on primary Y-axis */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$B$2:$B$10",
|
||||
chart->y_axis);
|
||||
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
/* Set marker style for series 1 - circle with blue fill */
|
||||
chart_series_set_marker_type(series1, LXW_CHART_MARKER_CIRCLE);
|
||||
chart_series_set_marker_size(series1, 5);
|
||||
|
||||
lxw_chart_fill marker1_fill = {.color = accent1_color};
|
||||
chart_series_set_marker_fill(series1, &marker1_fill);
|
||||
|
||||
lxw_chart_line marker1_line = {.color = accent1_color};
|
||||
chart_series_set_marker_line(series1, &marker1_line);
|
||||
|
||||
/* Remove connecting line for series 1 (markers only) */
|
||||
lxw_chart_line no_line = {.none = 1};
|
||||
chart_series_set_line(series1, &no_line);
|
||||
|
||||
printf("2. Added primary series (Velocity) with blue circle markers...\n");
|
||||
|
||||
/* Configure series 2 (Distance) on secondary Y-axis */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$C$2:$C$10",
|
||||
chart->y2_axis);
|
||||
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
/* Set marker style for series 2 - circle with orange fill */
|
||||
chart_series_set_marker_type(series2, LXW_CHART_MARKER_CIRCLE);
|
||||
chart_series_set_marker_size(series2, 5);
|
||||
|
||||
lxw_chart_fill marker2_fill = {.color = accent2_color};
|
||||
chart_series_set_marker_fill(series2, &marker2_fill);
|
||||
|
||||
lxw_chart_line marker2_line = {.color = accent2_color};
|
||||
chart_series_set_marker_line(series2, &marker2_line);
|
||||
|
||||
/* Remove connecting line for series 2 (markers only) */
|
||||
chart_series_set_line(series2, &no_line);
|
||||
|
||||
printf("3. Added secondary series (Distance) with orange circle markers...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Velocity (m/s) vs Distance (km)");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Time (hours)");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Velocity (m/s)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Distance (km)");
|
||||
|
||||
/* Position legend at bottom */
|
||||
chart_legend_set_position(chart, LXW_CHART_LEGEND_BOTTOM);
|
||||
|
||||
printf("4. Configured chart title, axis labels, and legend...\n");
|
||||
|
||||
/* Add the chart to the chartsheet (instead of inserting into worksheet) */
|
||||
chartsheet_set_chart(chartsheet, chart);
|
||||
|
||||
/* Make the chartsheet the active sheet when the workbook is opened */
|
||||
chartsheet_activate(chartsheet);
|
||||
|
||||
printf("5. Added chart to chartsheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_scatter_chartsheet.xlsx\n\n");
|
||||
printf("Styling features:\n");
|
||||
printf(" - Circle markers (size 5) for both series\n");
|
||||
printf(" - Series 1: Blue markers (accent1 approximation)\n");
|
||||
printf(" - Series 2: Orange markers (accent2 approximation)\n");
|
||||
printf(" - No connecting lines (markers only)\n");
|
||||
printf(" - Legend positioned at bottom\n");
|
||||
printf(" - Two Y-axes (left for Velocity, right for Distance)\n");
|
||||
printf(" - Chart in dedicated chartsheet (not embedded in worksheet)\n\n");
|
||||
printf("Open test_scatter_chartsheet.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
139
examples/test_scatter_styled.c
Normal file
139
examples/test_scatter_styled.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Test program to create a styled scatter chart matching test_scatter_y2_good.xlsx formatting.
|
||||
* Features:
|
||||
* - Circle markers with custom colors (blue/orange to approximate accent1/accent2)
|
||||
* - No lines connecting markers
|
||||
* - Legend at bottom
|
||||
* - Secondary Y-axis
|
||||
* - Formatted axis titles
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Styled Scatter Chart with Secondary Y-Axis ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_scatter_styled.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_SCATTER);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Time (hours)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Velocity (m/s)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Distance (km)", NULL);
|
||||
|
||||
/* Write time data (X-axis) */
|
||||
double time[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 0, time[i], NULL);
|
||||
}
|
||||
|
||||
/* Write velocity data (primary Y-axis, left side) */
|
||||
double velocity[] = {0, 5.5, 12.3, 18.7, 22.1, 23.8, 24.2, 24.5, 24.7};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, velocity[i], NULL);
|
||||
}
|
||||
|
||||
/* Write distance data (secondary Y-axis, right side) */
|
||||
double distance[] = {0, 5, 25, 70, 135, 215, 285, 385, 500};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, distance[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (9 time points, 2 series)...\n");
|
||||
|
||||
/* Configure colors to approximate Excel's accent1 (blue) and accent2 (orange) */
|
||||
lxw_color_t accent1_color = 0x4472C4; /* Excel default accent1: blue */
|
||||
lxw_color_t accent2_color = 0xED7D31; /* Excel default accent2: orange */
|
||||
|
||||
/* Configure series 1 (Velocity) on primary Y-axis */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$B$2:$B$10",
|
||||
chart->y_axis);
|
||||
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
/* Set marker style for series 1 - circle with blue fill */
|
||||
chart_series_set_marker_type(series1, LXW_CHART_MARKER_CIRCLE);
|
||||
chart_series_set_marker_size(series1, 5);
|
||||
|
||||
lxw_chart_fill marker1_fill = {.color = accent1_color};
|
||||
chart_series_set_marker_fill(series1, &marker1_fill);
|
||||
|
||||
lxw_chart_line marker1_line = {.color = accent1_color};
|
||||
chart_series_set_marker_line(series1, &marker1_line);
|
||||
|
||||
/* Remove connecting line for series 1 (markers only) */
|
||||
lxw_chart_line no_line = {.none = 1};
|
||||
chart_series_set_line(series1, &no_line);
|
||||
|
||||
printf("2. Added primary series (Velocity) with blue circle markers...\n");
|
||||
|
||||
/* Configure series 2 (Distance) on secondary Y-axis */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$C$2:$C$10",
|
||||
chart->y2_axis);
|
||||
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
/* Set marker style for series 2 - circle with orange fill */
|
||||
chart_series_set_marker_type(series2, LXW_CHART_MARKER_CIRCLE);
|
||||
chart_series_set_marker_size(series2, 5);
|
||||
|
||||
lxw_chart_fill marker2_fill = {.color = accent2_color};
|
||||
chart_series_set_marker_fill(series2, &marker2_fill);
|
||||
|
||||
lxw_chart_line marker2_line = {.color = accent2_color};
|
||||
chart_series_set_marker_line(series2, &marker2_line);
|
||||
|
||||
/* Remove connecting line for series 2 (markers only) */
|
||||
chart_series_set_line(series2, &no_line);
|
||||
|
||||
printf("3. Added secondary series (Distance) with orange circle markers...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Velocity (m/s) vs Distance (km)");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Time (hours)");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Velocity (m/s)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Distance (km)");
|
||||
|
||||
/* Position legend at bottom */
|
||||
chart_legend_set_position(chart, LXW_CHART_LEGEND_BOTTOM);
|
||||
|
||||
printf("4. Configured chart title, axis labels, and legend...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_scatter_styled.xlsx\n\n");
|
||||
printf("Styling features:\n");
|
||||
printf(" - Circle markers (size 5) for both series\n");
|
||||
printf(" - Series 1: Blue markers (accent1 approximation)\n");
|
||||
printf(" - Series 2: Orange markers (accent2 approximation)\n");
|
||||
printf(" - No connecting lines (markers only)\n");
|
||||
printf(" - Legend positioned at bottom\n");
|
||||
printf(" - Two Y-axes (left for Velocity, right for Distance)\n\n");
|
||||
printf("Open test_scatter_styled.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
113
examples/test_scatter_y2.c
Normal file
113
examples/test_scatter_y2.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Test program to verify scatter chart secondary Y-axis functionality.
|
||||
* Tests scatter chart with two series on different Y-axes.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Scatter Chart Secondary Y-Axis Test ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_scatter_y2.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_SCATTER);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Time (hours)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Velocity (m/s)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Distance (km)", NULL);
|
||||
|
||||
/* Write some data with different scales to demonstrate secondary axis. */
|
||||
/* Column A: X-axis values (time in hours) */
|
||||
double time[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 0, time[i], NULL);
|
||||
}
|
||||
|
||||
/* Column B: Small scale values - Velocity in m/s (primary Y-axis, left side) */
|
||||
double velocity[] = {0, 5.5, 12.3, 18.7, 22.1, 23.8, 24.2, 24.5, 24.7};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, velocity[i], NULL);
|
||||
}
|
||||
|
||||
/* Column C: Large scale values - Distance in km (secondary Y-axis, right side) */
|
||||
double distance[] = {0, 10, 35, 75, 130, 200, 285, 385, 500};
|
||||
for (int i = 0; i < 9; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, distance[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (9 time points, 2 series with different scales)...\n");
|
||||
|
||||
/* Add series to primary Y-axis (left side) - Velocity */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$B$2:$B$10",
|
||||
chart->y_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
printf("2. Added primary series (Velocity) to left Y-axis...\n");
|
||||
|
||||
/* Add series to secondary Y-axis (right side) - Distance */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$10",
|
||||
"=Data!$C$2:$C$10",
|
||||
chart->y2_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
printf("3. Added secondary series (Distance) to right Y-axis...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Velocity and Distance vs Time");
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Time (hours)");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Velocity (m/s)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Distance (km)");
|
||||
|
||||
/* Position the secondary Y-axis title on the right side of the chart */
|
||||
lxw_chart_layout layout = {
|
||||
.x = 0.686,
|
||||
.y = 0.314,
|
||||
.width = 0.0,
|
||||
.height = 0.0,
|
||||
.has_inner = LXW_FALSE
|
||||
};
|
||||
chart_axis_set_name_layout(chart->y2_axis, &layout);
|
||||
|
||||
printf("4. Configured chart title and axis labels...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_scatter_y2.xlsx\n\n");
|
||||
printf("Expected behavior:\n");
|
||||
printf(" - Scatter chart with TWO Y-axes\n");
|
||||
printf(" - Velocity series on left Y-axis (0-25 m/s range)\n");
|
||||
printf(" - Distance series on right Y-axis (0-500 km range)\n");
|
||||
printf(" - Both series plotted against time on X-axis\n");
|
||||
printf(" - Two scatterChart elements in the XML\n");
|
||||
printf(" - Four axes total (2 X-axes, 2 Y-axes)\n\n");
|
||||
printf("Open test_scatter_y2.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
81
examples/test_single_axis.c
Normal file
81
examples/test_single_axis.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Test program to verify single Y-axis functionality (baseline test).
|
||||
* This ensures our secondary axis changes didn't break normal charts.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Single Y-Axis Test (Baseline) ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_single_axis.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Sales");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Quarter", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Sales", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Profit", NULL);
|
||||
|
||||
printf("1. Writing test data...\n");
|
||||
|
||||
/* Write quarter labels */
|
||||
const char *quarters[] = {"Q1", "Q2", "Q3", "Q4"};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
worksheet_write_string(worksheet, i + 1, 0, quarters[i], NULL);
|
||||
}
|
||||
|
||||
/* Write sales data */
|
||||
double sales[] = {120, 180, 220, 195};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, sales[i], NULL);
|
||||
}
|
||||
|
||||
/* Write profit data */
|
||||
double profit[] = {45, 68, 82, 71};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, profit[i], NULL);
|
||||
}
|
||||
|
||||
printf("2. Adding two series to PRIMARY Y-axis only...\n");
|
||||
|
||||
/* Add first series - Sales (using default/primary axis) */
|
||||
lxw_chart_series *series1 = chart_add_series(chart,
|
||||
"=Sales!$A$2:$A$5",
|
||||
"=Sales!$B$2:$B$5");
|
||||
chart_series_set_name(series1, "=Sales!$B$1");
|
||||
|
||||
/* Add second series - Profit (using default/primary axis) */
|
||||
lxw_chart_series *series2 = chart_add_series(chart,
|
||||
"=Sales!$A$2:$A$5",
|
||||
"=Sales!$C$2:$C$5");
|
||||
chart_series_set_name(series2, "=Sales!$C$1");
|
||||
|
||||
printf("3. Configuring chart...\n");
|
||||
|
||||
/* Configure chart */
|
||||
chart_title_set_name(chart, "Quarterly Sales and Profit");
|
||||
chart_axis_set_name(chart->x_axis, "Quarter");
|
||||
chart_axis_set_name(chart->y_axis, "Amount ($K)");
|
||||
|
||||
/* Insert chart */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("4. Saving workbook...\n");
|
||||
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_single_axis.xlsx\n\n");
|
||||
printf("Expected behavior:\n");
|
||||
printf(" - Chart with ONE Y-axis (standard chart)\n");
|
||||
printf(" - Two series (Sales and Profit) on same scale\n");
|
||||
printf(" - Chart style and color files should still be generated\n\n");
|
||||
printf("This verifies our changes didn't break normal charts!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
116
examples/test_y2_axis.c
Normal file
116
examples/test_y2_axis.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Comprehensive test program to verify secondary Y-axis functionality.
|
||||
* Tests chart style files, color files, and relationships generation.
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("=== Secondary Y-Axis Test ===\n\n");
|
||||
|
||||
lxw_workbook *workbook = workbook_new("test_secondary_axis.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, "Data");
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
lxw_chart_series *series1, *series2;
|
||||
|
||||
/* Write headers */
|
||||
worksheet_write_string(worksheet, 0, 0, "Month", NULL);
|
||||
worksheet_write_string(worksheet, 0, 1, "Temperature (°C)", NULL);
|
||||
worksheet_write_string(worksheet, 0, 2, "Revenue ($1000s)", NULL);
|
||||
|
||||
/* Write some data with different scales to demonstrate secondary axis. */
|
||||
/* Column A: X-axis values (months) */
|
||||
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_string(worksheet, i + 1, 0, months[i], NULL);
|
||||
}
|
||||
|
||||
/* Column B: Small scale values - Temperature (primary Y-axis, left side) */
|
||||
double temperatures[] = {5.2, 7.8, 12.5, 16.3, 21.7, 25.4, 28.1, 26.8};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 1, temperatures[i], NULL);
|
||||
}
|
||||
|
||||
/* Column C: Large scale values - Revenue (secondary Y-axis, right side) */
|
||||
double revenue[] = {1250, 1580, 2340, 2890, 3420, 3950, 4200, 3880};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
worksheet_write_number(worksheet, i + 1, 2, revenue[i], NULL);
|
||||
}
|
||||
|
||||
printf("1. Writing test data (8 months, 2 series with different scales)...\n");
|
||||
|
||||
/* Add series to primary Y-axis (left side) - Temperature */
|
||||
series1 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$9",
|
||||
"=Data!$B$2:$B$9",
|
||||
chart->y_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series1, "=Data!$B$1");
|
||||
|
||||
printf("2. Added primary series (Temperature) to left Y-axis...\n");
|
||||
|
||||
/* Add series to secondary Y-axis (right side) - Revenue */
|
||||
series2 = chart_add_series_on_axis(chart,
|
||||
"=Data!$A$2:$A$9",
|
||||
"=Data!$C$2:$C$9",
|
||||
chart->y2_axis);
|
||||
|
||||
/* Set series name */
|
||||
chart_series_set_name(series2, "=Data!$C$1");
|
||||
|
||||
printf("3. Added secondary series (Revenue) to right Y-axis...\n");
|
||||
|
||||
/* Configure chart title */
|
||||
chart_title_set_name(chart, "Monthly Temperature vs Revenue");
|
||||
|
||||
/* Configure primary Y-axis (left side) */
|
||||
chart_axis_set_name(chart->y_axis, "Temperature (°C)");
|
||||
|
||||
/* Configure secondary Y-axis (right side) */
|
||||
chart_axis_set_name(chart->y2_axis, "Revenue ($1000s)");
|
||||
|
||||
/* Position the secondary Y-axis title on the right side of the chart */
|
||||
lxw_chart_layout layout = {
|
||||
.x = 0.686,
|
||||
.y = 0.314,
|
||||
.width = 0.0,
|
||||
.height = 0.0,
|
||||
.has_inner = LXW_FALSE
|
||||
};
|
||||
chart_axis_set_name_layout(chart->y2_axis, &layout);
|
||||
|
||||
/* Configure X-axis */
|
||||
chart_axis_set_name(chart->x_axis, "Month");
|
||||
|
||||
printf("4. Configured chart title and axis labels...\n");
|
||||
|
||||
/* Insert the chart into the worksheet */
|
||||
worksheet_insert_chart(worksheet, CELL("E2"), chart);
|
||||
|
||||
printf("5. Inserted chart into worksheet...\n");
|
||||
|
||||
/* Save the workbook */
|
||||
printf("6. Saving workbook...\n");
|
||||
lxw_error result = workbook_close(workbook);
|
||||
|
||||
if (result == LXW_NO_ERROR) {
|
||||
printf("\n✓ SUCCESS! Created test_secondary_axis.xlsx\n\n");
|
||||
printf("Expected files in the XLSX package:\n");
|
||||
printf(" - xl/charts/chart1.xml (main chart definition)\n");
|
||||
printf(" - xl/charts/style1.xml (chart style - NEW!)\n");
|
||||
printf(" - xl/charts/colors1.xml (chart colors - NEW!)\n");
|
||||
printf(" - xl/charts/_rels/chart1.xml.rels (relationships - NEW!)\n");
|
||||
printf(" - [Content_Types].xml (with style/color registrations - NEW!)\n\n");
|
||||
printf("The chart should display:\n");
|
||||
printf(" - Temperature line on left Y-axis (0-30°C range)\n");
|
||||
printf(" - Revenue line on right Y-axis (0-4500k range)\n");
|
||||
printf(" - Both series properly scaled and visible\n\n");
|
||||
printf("Open test_secondary_axis.xlsx in Excel to verify!\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n✗ ERROR creating workbook: %d\n", result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1025,6 +1025,9 @@ typedef enum lxw_chart_trendline_type {
|
|||
LXW_CHART_TRENDLINE_TYPE_AVERAGE
|
||||
} lxw_chart_trendline_type;
|
||||
|
||||
/* Forward declaration for lxw_chart_axis. */
|
||||
struct lxw_chart_axis;
|
||||
|
||||
/**
|
||||
* @brief Struct to represent an Excel chart data series.
|
||||
*
|
||||
|
|
@ -1037,6 +1040,7 @@ typedef struct lxw_chart_series {
|
|||
lxw_series_range *categories;
|
||||
lxw_series_range *values;
|
||||
lxw_chart_title title;
|
||||
struct lxw_chart_axis *y_axis;
|
||||
lxw_chart_line *line;
|
||||
lxw_chart_fill *fill;
|
||||
lxw_chart_pattern *pattern;
|
||||
|
|
@ -1185,6 +1189,12 @@ typedef struct lxw_chart {
|
|||
*/
|
||||
lxw_chart_axis *y_axis;
|
||||
|
||||
/**
|
||||
* A pointer to the chart y2_axis object which can be used in functions
|
||||
* that configure the secondary Y axis.
|
||||
*/
|
||||
lxw_chart_axis *y2_axis;
|
||||
|
||||
lxw_chart_title title;
|
||||
|
||||
uint32_t id;
|
||||
|
|
@ -1354,6 +1364,43 @@ lxw_chart_series *chart_add_series(lxw_chart *chart,
|
|||
const char *categories,
|
||||
const char *values);
|
||||
|
||||
/**
|
||||
* @brief Add a data series to a chart on a specified Y-axis.
|
||||
*
|
||||
* @param chart Pointer to a lxw_chart instance to be configured.
|
||||
* @param categories The range of categories in the data series.
|
||||
* @param values The range of values in the data series.
|
||||
* @param y_axis Pointer to Y-axis (chart->y_axis, chart->y2_axis, or NULL for primary).
|
||||
*
|
||||
* @return A lxw_chart_series object pointer.
|
||||
*
|
||||
* This function works the same as chart_add_series() but allows you to specify
|
||||
* which Y-axis the series should be plotted against. This is useful when you
|
||||
* want to plot series with different scales on the same chart.
|
||||
*
|
||||
* @code
|
||||
* // Add series to secondary Y-axis (right side)
|
||||
* chart_add_series_on_axis(chart, "=Sheet1!$A$2:$A$7",
|
||||
* "=Sheet1!$C$2:$C$7", chart->y2_axis);
|
||||
*
|
||||
* // Add series to primary Y-axis (left side)
|
||||
* chart_add_series_on_axis(chart, "=Sheet1!$A$2:$A$7",
|
||||
* "=Sheet1!$B$2:$B$7", chart->y_axis);
|
||||
*
|
||||
* // Configure the secondary Y-axis
|
||||
* chart_axis_set_name(chart->y2_axis, "Secondary Axis");
|
||||
* @endcode
|
||||
*
|
||||
* Pass NULL for y_axis to use the primary Y-axis (chart->y_axis).
|
||||
*
|
||||
* Note: Not all chart types support secondary axes. Pie, doughnut, and radar
|
||||
* charts will return NULL if you attempt to add a series to a secondary axis.
|
||||
*/
|
||||
lxw_chart_series *chart_add_series_on_axis(lxw_chart *chart,
|
||||
const char *categories,
|
||||
const char *values,
|
||||
lxw_chart_axis *y_axis);
|
||||
|
||||
/**
|
||||
* @brief Set a series "categories" range using row and column values.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -110,9 +110,6 @@ typedef enum lxw_error {
|
|||
/** Function string parameter is empty. */
|
||||
LXW_ERROR_PARAMETER_IS_EMPTY,
|
||||
|
||||
/** A #lxw_datetime parameter has a validation error. */
|
||||
LXW_ERROR_DATETIME_VALIDATION,
|
||||
|
||||
/** Worksheet name exceeds Excel's limit of 31 characters. */
|
||||
LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED,
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ void lxw_ct_add_chartsheet_name(lxw_content_types *content_types,
|
|||
const char *name);
|
||||
void lxw_ct_add_chart_name(lxw_content_types *content_types,
|
||||
const char *name);
|
||||
void lxw_ct_add_chart_style_name(lxw_content_types *content_types,
|
||||
const char *name);
|
||||
void lxw_ct_add_chart_colors_name(lxw_content_types *content_types,
|
||||
const char *name);
|
||||
void lxw_ct_add_drawing_name(lxw_content_types *content_types,
|
||||
const char *name);
|
||||
void lxw_ct_add_table_name(lxw_content_types *content_types,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ void lxw_add_ms_package_relationship(lxw_relationships *self,
|
|||
void lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
|
||||
const char *target,
|
||||
const char *target_mode);
|
||||
void lxw_add_chart_style_relationship(lxw_relationships *self);
|
||||
void lxw_add_chart_color_relationship(lxw_relationships *self);
|
||||
void lxw_add_rich_value_relationship(lxw_relationships *self);
|
||||
|
||||
/* Declarations required for unit testing. */
|
||||
|
|
|
|||
|
|
@ -212,30 +212,6 @@ double lxw_datetime_to_excel_datetime(lxw_datetime *datetime);
|
|||
double lxw_datetime_to_excel_date_with_epoch(lxw_datetime *datetime,
|
||||
uint8_t use_1904_epoch);
|
||||
|
||||
/**
|
||||
* @brief Validate a #lxw_datetime struct.
|
||||
*
|
||||
* Validates a #lxw_datetime struct to ensure its fields are within acceptable
|
||||
* ranges for Excel dates and times.
|
||||
*
|
||||
* The members of the #lxw_datetime struct and the range of their values are:
|
||||
*
|
||||
* Member | Value
|
||||
* -------- | -----------
|
||||
* year | 1900 - 9999
|
||||
* month | 1 - 12
|
||||
* day | 1 - 31
|
||||
* hour | 0 - 23
|
||||
* min | 0 - 59
|
||||
* sec | 0 - 59.999
|
||||
*
|
||||
* @param datetime A pointer to a #lxw_datetime struct.
|
||||
*
|
||||
* @return A #lxw_error code. Either #LXW_NO_ERROR or
|
||||
* #LXW_ERROR_DATETIME_VALIDATION if a field is out of range.
|
||||
*/
|
||||
lxw_error lxw_datetime_validate(lxw_datetime *datetime);
|
||||
|
||||
/**
|
||||
* @brief Converts a unix datetime to an Excel datetime number.
|
||||
*
|
||||
|
|
|
|||
804
libxlsxwriter_LV.h
Normal file
804
libxlsxwriter_LV.h
Normal file
|
|
@ -0,0 +1,804 @@
|
|||
/*
|
||||
* libxlsxwriter_LV.h - Combined public API header for libxlsxwriter
|
||||
*
|
||||
* This header contains all public exported API functions with standard
|
||||
* C calling convention (__stdcall/WINAPI) declarations.
|
||||
* All macros have been expanded to their equivalent code.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
* Copyright 2014-2025, John McNamara, jmcnamara@cpan.org.
|
||||
*
|
||||
* Generated for LabVIEW integration.
|
||||
*/
|
||||
|
||||
#ifndef __LIBXLSXWRITER_LV_H__
|
||||
#define __LIBXLSXWRITER_LV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================
|
||||
* Calling Convention Definition
|
||||
* ============================================================================ */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define LXW_CALL __stdcall
|
||||
#else
|
||||
#define LXW_CALL
|
||||
#endif
|
||||
|
||||
/* ============================================================================
|
||||
* Basic Type Definitions
|
||||
* ============================================================================ */
|
||||
|
||||
/** Integer data type to represent a row value (max 1,048,576). */
|
||||
typedef uint32_t lxw_row_t;
|
||||
|
||||
/** Integer data type to represent a column value (max 16,384). */
|
||||
typedef uint16_t lxw_col_t;
|
||||
|
||||
/** The type for RGB colors (0x000000 to 0xFFFFFF). */
|
||||
typedef uint32_t lxw_color_t;
|
||||
|
||||
/* ============================================================================
|
||||
* Boolean Values
|
||||
* ============================================================================ */
|
||||
|
||||
enum lxw_boolean {
|
||||
LXW_FALSE = 0,
|
||||
LXW_TRUE = 1,
|
||||
LXW_EXPLICIT_FALSE = 2
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* Error Codes
|
||||
* ============================================================================ */
|
||||
|
||||
typedef enum lxw_error {
|
||||
LXW_NO_ERROR = 0,
|
||||
LXW_ERROR_MEMORY_MALLOC_FAILED,
|
||||
LXW_ERROR_CREATING_XLSX_FILE,
|
||||
LXW_ERROR_CREATING_TMPFILE,
|
||||
LXW_ERROR_READING_TMPFILE,
|
||||
LXW_ERROR_ZIP_FILE_OPERATION,
|
||||
LXW_ERROR_ZIP_PARAMETER_ERROR,
|
||||
LXW_ERROR_ZIP_BAD_ZIP_FILE,
|
||||
LXW_ERROR_ZIP_INTERNAL_ERROR,
|
||||
LXW_ERROR_ZIP_FILE_ADD,
|
||||
LXW_ERROR_ZIP_CLOSE,
|
||||
LXW_ERROR_FEATURE_NOT_SUPPORTED,
|
||||
LXW_ERROR_NULL_PARAMETER_IGNORED,
|
||||
LXW_ERROR_PARAMETER_VALIDATION,
|
||||
LXW_ERROR_PARAMETER_IS_EMPTY,
|
||||
LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_INVALID_SHEETNAME_CHARACTER,
|
||||
LXW_ERROR_SHEETNAME_START_END_APOSTROPHE,
|
||||
LXW_ERROR_SHEETNAME_ALREADY_USED,
|
||||
LXW_ERROR_32_STRING_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_128_STRING_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_255_STRING_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND,
|
||||
LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE,
|
||||
LXW_ERROR_WORKSHEET_MAX_URL_LENGTH_EXCEEDED,
|
||||
LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED,
|
||||
LXW_ERROR_IMAGE_DIMENSIONS,
|
||||
LXW_MAX_ERRNO
|
||||
} lxw_error;
|
||||
|
||||
/* ============================================================================
|
||||
* Datetime Structure
|
||||
* ============================================================================ */
|
||||
|
||||
typedef struct lxw_datetime {
|
||||
int year; /* 1900 - 9999 */
|
||||
int month; /* 1 - 12 */
|
||||
int day; /* 1 - 31 */
|
||||
int hour; /* 0 - 23 */
|
||||
int min; /* 0 - 59 */
|
||||
double sec; /* 0 - 59.999 */
|
||||
} lxw_datetime;
|
||||
|
||||
/* ============================================================================
|
||||
* Chart Types
|
||||
* ============================================================================ */
|
||||
|
||||
typedef enum lxw_chart_type {
|
||||
LXW_CHART_NONE = 0,
|
||||
LXW_CHART_AREA,
|
||||
LXW_CHART_AREA_STACKED,
|
||||
LXW_CHART_AREA_STACKED_PERCENT,
|
||||
LXW_CHART_BAR,
|
||||
LXW_CHART_BAR_STACKED,
|
||||
LXW_CHART_BAR_STACKED_PERCENT,
|
||||
LXW_CHART_COLUMN,
|
||||
LXW_CHART_COLUMN_STACKED,
|
||||
LXW_CHART_COLUMN_STACKED_PERCENT,
|
||||
LXW_CHART_DOUGHNUT,
|
||||
LXW_CHART_LINE,
|
||||
LXW_CHART_LINE_STACKED,
|
||||
LXW_CHART_LINE_STACKED_PERCENT,
|
||||
LXW_CHART_PIE,
|
||||
LXW_CHART_SCATTER,
|
||||
LXW_CHART_SCATTER_STRAIGHT,
|
||||
LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS,
|
||||
LXW_CHART_SCATTER_SMOOTH,
|
||||
LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS,
|
||||
LXW_CHART_RADAR,
|
||||
LXW_CHART_RADAR_WITH_MARKERS,
|
||||
LXW_CHART_RADAR_FILLED
|
||||
} lxw_chart_type;
|
||||
|
||||
typedef enum lxw_chart_legend_position {
|
||||
LXW_CHART_LEGEND_NONE = 0,
|
||||
LXW_CHART_LEGEND_RIGHT,
|
||||
LXW_CHART_LEGEND_LEFT,
|
||||
LXW_CHART_LEGEND_TOP,
|
||||
LXW_CHART_LEGEND_BOTTOM,
|
||||
LXW_CHART_LEGEND_TOP_RIGHT,
|
||||
LXW_CHART_LEGEND_OVERLAY_RIGHT,
|
||||
LXW_CHART_LEGEND_OVERLAY_LEFT,
|
||||
LXW_CHART_LEGEND_OVERLAY_TOP_RIGHT
|
||||
} lxw_chart_legend_position;
|
||||
|
||||
typedef enum lxw_chart_line_dash_type {
|
||||
LXW_CHART_LINE_DASH_SOLID = 0,
|
||||
LXW_CHART_LINE_DASH_ROUND_DOT,
|
||||
LXW_CHART_LINE_DASH_SQUARE_DOT,
|
||||
LXW_CHART_LINE_DASH_DASH,
|
||||
LXW_CHART_LINE_DASH_DASH_DOT,
|
||||
LXW_CHART_LINE_DASH_LONG_DASH,
|
||||
LXW_CHART_LINE_DASH_LONG_DASH_DOT,
|
||||
LXW_CHART_LINE_DASH_LONG_DASH_DOT_DOT,
|
||||
LXW_CHART_LINE_DASH_DOT,
|
||||
LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT,
|
||||
LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT_DOT
|
||||
} lxw_chart_line_dash_type;
|
||||
|
||||
typedef enum lxw_chart_marker_type {
|
||||
LXW_CHART_MARKER_AUTOMATIC,
|
||||
LXW_CHART_MARKER_NONE,
|
||||
LXW_CHART_MARKER_SQUARE,
|
||||
LXW_CHART_MARKER_DIAMOND,
|
||||
LXW_CHART_MARKER_TRIANGLE,
|
||||
LXW_CHART_MARKER_X,
|
||||
LXW_CHART_MARKER_STAR,
|
||||
LXW_CHART_MARKER_SHORT_DASH,
|
||||
LXW_CHART_MARKER_LONG_DASH,
|
||||
LXW_CHART_MARKER_CIRCLE,
|
||||
LXW_CHART_MARKER_PLUS
|
||||
} lxw_chart_marker_type;
|
||||
|
||||
typedef enum lxw_chart_label_position {
|
||||
LXW_CHART_LABEL_POSITION_DEFAULT,
|
||||
LXW_CHART_LABEL_POSITION_CENTER,
|
||||
LXW_CHART_LABEL_POSITION_RIGHT,
|
||||
LXW_CHART_LABEL_POSITION_LEFT,
|
||||
LXW_CHART_LABEL_POSITION_ABOVE,
|
||||
LXW_CHART_LABEL_POSITION_BELOW,
|
||||
LXW_CHART_LABEL_POSITION_INSIDE_BASE,
|
||||
LXW_CHART_LABEL_POSITION_INSIDE_END,
|
||||
LXW_CHART_LABEL_POSITION_OUTSIDE_END,
|
||||
LXW_CHART_LABEL_POSITION_BEST_FIT
|
||||
} lxw_chart_label_position;
|
||||
|
||||
typedef enum lxw_chart_label_separator {
|
||||
LXW_CHART_LABEL_SEPARATOR_COMMA,
|
||||
LXW_CHART_LABEL_SEPARATOR_SEMICOLON,
|
||||
LXW_CHART_LABEL_SEPARATOR_PERIOD,
|
||||
LXW_CHART_LABEL_SEPARATOR_NEWLINE,
|
||||
LXW_CHART_LABEL_SEPARATOR_SPACE
|
||||
} lxw_chart_label_separator;
|
||||
|
||||
typedef enum lxw_chart_axis_tick_position {
|
||||
LXW_CHART_AXIS_POSITION_DEFAULT,
|
||||
LXW_CHART_AXIS_POSITION_ON_TICK,
|
||||
LXW_CHART_AXIS_POSITION_BETWEEN
|
||||
} lxw_chart_axis_tick_position;
|
||||
|
||||
typedef enum lxw_chart_axis_label_position {
|
||||
LXW_CHART_AXIS_LABEL_POSITION_NEXT_TO,
|
||||
LXW_CHART_AXIS_LABEL_POSITION_HIGH,
|
||||
LXW_CHART_AXIS_LABEL_POSITION_LOW,
|
||||
LXW_CHART_AXIS_LABEL_POSITION_NONE
|
||||
} lxw_chart_axis_label_position;
|
||||
|
||||
typedef enum lxw_chart_axis_label_alignment {
|
||||
LXW_CHART_AXIS_LABEL_ALIGN_CENTER,
|
||||
LXW_CHART_AXIS_LABEL_ALIGN_LEFT,
|
||||
LXW_CHART_AXIS_LABEL_ALIGN_RIGHT
|
||||
} lxw_chart_axis_label_alignment;
|
||||
|
||||
typedef enum lxw_chart_axis_display_unit {
|
||||
LXW_CHART_AXIS_UNITS_NONE,
|
||||
LXW_CHART_AXIS_UNITS_HUNDREDS,
|
||||
LXW_CHART_AXIS_UNITS_THOUSANDS,
|
||||
LXW_CHART_AXIS_UNITS_TEN_THOUSANDS,
|
||||
LXW_CHART_AXIS_UNITS_HUNDRED_THOUSANDS,
|
||||
LXW_CHART_AXIS_UNITS_MILLIONS,
|
||||
LXW_CHART_AXIS_UNITS_TEN_MILLIONS,
|
||||
LXW_CHART_AXIS_UNITS_HUNDRED_MILLIONS,
|
||||
LXW_CHART_AXIS_UNITS_BILLIONS,
|
||||
LXW_CHART_AXIS_UNITS_TRILLIONS
|
||||
} lxw_chart_axis_display_unit;
|
||||
|
||||
typedef enum lxw_chart_axis_tick_mark {
|
||||
LXW_CHART_AXIS_TICK_MARK_DEFAULT,
|
||||
LXW_CHART_AXIS_TICK_MARK_NONE,
|
||||
LXW_CHART_AXIS_TICK_MARK_INSIDE,
|
||||
LXW_CHART_AXIS_TICK_MARK_OUTSIDE,
|
||||
LXW_CHART_AXIS_TICK_MARK_CROSSING
|
||||
} lxw_chart_tick_mark;
|
||||
|
||||
typedef enum lxw_chart_blank {
|
||||
LXW_CHART_BLANKS_AS_GAP,
|
||||
LXW_CHART_BLANKS_AS_ZERO,
|
||||
LXW_CHART_BLANKS_AS_CONNECTED
|
||||
} lxw_chart_blank;
|
||||
|
||||
typedef enum lxw_chart_error_bar_type {
|
||||
LXW_CHART_ERROR_BAR_TYPE_STD_ERROR,
|
||||
LXW_CHART_ERROR_BAR_TYPE_FIXED,
|
||||
LXW_CHART_ERROR_BAR_TYPE_PERCENTAGE,
|
||||
LXW_CHART_ERROR_BAR_TYPE_STD_DEV
|
||||
} lxw_chart_error_bar_type;
|
||||
|
||||
typedef enum lxw_chart_error_bar_direction {
|
||||
LXW_CHART_ERROR_BAR_DIR_BOTH,
|
||||
LXW_CHART_ERROR_BAR_DIR_PLUS,
|
||||
LXW_CHART_ERROR_BAR_DIR_MINUS
|
||||
} lxw_chart_error_bar_direction;
|
||||
|
||||
typedef enum lxw_chart_error_bar_cap {
|
||||
LXW_CHART_ERROR_BAR_END_CAP,
|
||||
LXW_CHART_ERROR_BAR_NO_CAP
|
||||
} lxw_chart_error_bar_cap;
|
||||
|
||||
typedef enum lxw_chart_trendline_type {
|
||||
LXW_CHART_TRENDLINE_TYPE_LINEAR,
|
||||
LXW_CHART_TRENDLINE_TYPE_LOG,
|
||||
LXW_CHART_TRENDLINE_TYPE_POLY,
|
||||
LXW_CHART_TRENDLINE_TYPE_POWER,
|
||||
LXW_CHART_TRENDLINE_TYPE_EXP,
|
||||
LXW_CHART_TRENDLINE_TYPE_AVERAGE
|
||||
} lxw_chart_trendline_type;
|
||||
|
||||
/* ============================================================================
|
||||
* Format Enums
|
||||
* ============================================================================ */
|
||||
|
||||
enum lxw_format_underlines {
|
||||
LXW_UNDERLINE_NONE = 0,
|
||||
LXW_UNDERLINE_SINGLE,
|
||||
LXW_UNDERLINE_DOUBLE,
|
||||
LXW_UNDERLINE_SINGLE_ACCOUNTING,
|
||||
LXW_UNDERLINE_DOUBLE_ACCOUNTING
|
||||
};
|
||||
|
||||
enum lxw_format_scripts {
|
||||
LXW_FONT_SUPERSCRIPT = 1,
|
||||
LXW_FONT_SUBSCRIPT
|
||||
};
|
||||
|
||||
enum lxw_format_alignments {
|
||||
LXW_ALIGN_NONE = 0,
|
||||
LXW_ALIGN_LEFT,
|
||||
LXW_ALIGN_CENTER,
|
||||
LXW_ALIGN_RIGHT,
|
||||
LXW_ALIGN_FILL,
|
||||
LXW_ALIGN_JUSTIFY,
|
||||
LXW_ALIGN_CENTER_ACROSS,
|
||||
LXW_ALIGN_DISTRIBUTED,
|
||||
LXW_ALIGN_VERTICAL_TOP,
|
||||
LXW_ALIGN_VERTICAL_BOTTOM,
|
||||
LXW_ALIGN_VERTICAL_CENTER,
|
||||
LXW_ALIGN_VERTICAL_JUSTIFY,
|
||||
LXW_ALIGN_VERTICAL_DISTRIBUTED
|
||||
};
|
||||
|
||||
enum lxw_format_diagonal_types {
|
||||
LXW_DIAGONAL_BORDER_UP = 1,
|
||||
LXW_DIAGONAL_BORDER_DOWN,
|
||||
LXW_DIAGONAL_BORDER_UP_DOWN
|
||||
};
|
||||
|
||||
enum lxw_defined_colors {
|
||||
LXW_COLOR_BLACK = 0x1000000,
|
||||
LXW_COLOR_BLUE = 0x0000FF,
|
||||
LXW_COLOR_BROWN = 0x800000,
|
||||
LXW_COLOR_CYAN = 0x00FFFF,
|
||||
LXW_COLOR_GRAY = 0x808080,
|
||||
LXW_COLOR_GREEN = 0x008000,
|
||||
LXW_COLOR_LIME = 0x00FF00,
|
||||
LXW_COLOR_MAGENTA = 0xFF00FF,
|
||||
LXW_COLOR_NAVY = 0x000080,
|
||||
LXW_COLOR_ORANGE = 0xFF6600,
|
||||
LXW_COLOR_PINK = 0xFF00FF,
|
||||
LXW_COLOR_PURPLE = 0x800080,
|
||||
LXW_COLOR_RED = 0xFF0000,
|
||||
LXW_COLOR_SILVER = 0xC0C0C0,
|
||||
LXW_COLOR_WHITE = 0xFFFFFF,
|
||||
LXW_COLOR_YELLOW = 0xFFFF00
|
||||
};
|
||||
|
||||
enum lxw_format_patterns {
|
||||
LXW_PATTERN_NONE = 0,
|
||||
LXW_PATTERN_SOLID,
|
||||
LXW_PATTERN_MEDIUM_GRAY,
|
||||
LXW_PATTERN_DARK_GRAY,
|
||||
LXW_PATTERN_LIGHT_GRAY,
|
||||
LXW_PATTERN_DARK_HORIZONTAL,
|
||||
LXW_PATTERN_DARK_VERTICAL,
|
||||
LXW_PATTERN_DARK_DOWN,
|
||||
LXW_PATTERN_DARK_UP,
|
||||
LXW_PATTERN_DARK_GRID,
|
||||
LXW_PATTERN_DARK_TRELLIS,
|
||||
LXW_PATTERN_LIGHT_HORIZONTAL,
|
||||
LXW_PATTERN_LIGHT_VERTICAL,
|
||||
LXW_PATTERN_LIGHT_DOWN,
|
||||
LXW_PATTERN_LIGHT_UP,
|
||||
LXW_PATTERN_LIGHT_GRID,
|
||||
LXW_PATTERN_LIGHT_TRELLIS,
|
||||
LXW_PATTERN_GRAY_125,
|
||||
LXW_PATTERN_GRAY_0625
|
||||
};
|
||||
|
||||
enum lxw_format_borders {
|
||||
LXW_BORDER_NONE,
|
||||
LXW_BORDER_THIN,
|
||||
LXW_BORDER_MEDIUM,
|
||||
LXW_BORDER_DASHED,
|
||||
LXW_BORDER_DOTTED,
|
||||
LXW_BORDER_THICK,
|
||||
LXW_BORDER_DOUBLE,
|
||||
LXW_BORDER_HAIR,
|
||||
LXW_BORDER_MEDIUM_DASHED,
|
||||
LXW_BORDER_DASH_DOT,
|
||||
LXW_BORDER_MEDIUM_DASH_DOT,
|
||||
LXW_BORDER_DASH_DOT_DOT,
|
||||
LXW_BORDER_MEDIUM_DASH_DOT_DOT,
|
||||
LXW_BORDER_SLANT_DASH_DOT
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* Forward Declarations (Opaque Pointers)
|
||||
* ============================================================================ */
|
||||
|
||||
typedef struct lxw_workbook lxw_workbook;
|
||||
typedef struct lxw_worksheet lxw_worksheet;
|
||||
typedef struct lxw_chartsheet lxw_chartsheet;
|
||||
typedef struct lxw_chart lxw_chart;
|
||||
typedef struct lxw_chart_series lxw_chart_series;
|
||||
typedef struct lxw_chart_axis lxw_chart_axis;
|
||||
typedef struct lxw_format lxw_format;
|
||||
typedef struct lxw_chart_line lxw_chart_line;
|
||||
typedef struct lxw_chart_fill lxw_chart_fill;
|
||||
typedef struct lxw_chart_pattern lxw_chart_pattern;
|
||||
typedef struct lxw_chart_font lxw_chart_font;
|
||||
typedef struct lxw_chart_layout lxw_chart_layout;
|
||||
typedef struct lxw_chart_point lxw_chart_point;
|
||||
typedef struct lxw_chart_data_label lxw_chart_data_label;
|
||||
typedef struct lxw_series_error_bars lxw_series_error_bars;
|
||||
typedef struct lxw_row_col_options lxw_row_col_options;
|
||||
typedef struct lxw_image_options lxw_image_options;
|
||||
typedef struct lxw_chart_options lxw_chart_options;
|
||||
typedef struct lxw_protection lxw_protection;
|
||||
typedef struct lxw_header_footer_options lxw_header_footer_options;
|
||||
typedef struct lxw_data_validation lxw_data_validation;
|
||||
typedef struct lxw_conditional_format lxw_conditional_format;
|
||||
typedef struct lxw_button_options lxw_button_options;
|
||||
typedef struct lxw_table_options lxw_table_options;
|
||||
typedef struct lxw_filter_rule lxw_filter_rule;
|
||||
typedef struct lxw_rich_string_tuple lxw_rich_string_tuple;
|
||||
typedef struct lxw_comment_options lxw_comment_options;
|
||||
typedef struct lxw_workbook_options lxw_workbook_options;
|
||||
typedef struct lxw_doc_properties lxw_doc_properties;
|
||||
|
||||
/* ============================================================================
|
||||
* Chart Line/Fill/Pattern Structures (for inline initialization)
|
||||
* ============================================================================ */
|
||||
|
||||
struct lxw_chart_line {
|
||||
lxw_color_t color;
|
||||
uint8_t none;
|
||||
float width;
|
||||
uint8_t dash_type;
|
||||
uint8_t transparency;
|
||||
};
|
||||
|
||||
struct lxw_chart_fill {
|
||||
lxw_color_t color;
|
||||
uint8_t none;
|
||||
uint8_t transparency;
|
||||
};
|
||||
|
||||
struct lxw_chart_pattern {
|
||||
lxw_color_t fg_color;
|
||||
lxw_color_t bg_color;
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
struct lxw_chart_font {
|
||||
const char *name;
|
||||
double size;
|
||||
uint8_t bold;
|
||||
uint8_t italic;
|
||||
uint8_t underline;
|
||||
int32_t rotation;
|
||||
lxw_color_t color;
|
||||
uint8_t pitch_family;
|
||||
uint8_t charset;
|
||||
int8_t baseline;
|
||||
};
|
||||
|
||||
struct lxw_chart_layout {
|
||||
double x;
|
||||
double y;
|
||||
double width;
|
||||
double height;
|
||||
uint8_t has_inner;
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* WORKBOOK FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
lxw_workbook * LXW_CALL workbook_new(const char *filename);
|
||||
lxw_workbook * LXW_CALL workbook_new_opt(const char *filename, lxw_workbook_options *options);
|
||||
lxw_worksheet * LXW_CALL workbook_add_worksheet(lxw_workbook *workbook, const char *sheetname);
|
||||
lxw_chartsheet * LXW_CALL workbook_add_chartsheet(lxw_workbook *workbook, const char *sheetname);
|
||||
lxw_format * LXW_CALL workbook_add_format(lxw_workbook *workbook);
|
||||
lxw_chart * LXW_CALL workbook_add_chart(lxw_workbook *workbook, uint8_t chart_type);
|
||||
lxw_error LXW_CALL workbook_close(lxw_workbook *workbook);
|
||||
lxw_error LXW_CALL workbook_set_properties(lxw_workbook *workbook, lxw_doc_properties *properties);
|
||||
lxw_error LXW_CALL workbook_set_custom_property_string(lxw_workbook *workbook, const char *name, const char *value);
|
||||
lxw_error LXW_CALL workbook_set_custom_property_number(lxw_workbook *workbook, const char *name, double value);
|
||||
lxw_error LXW_CALL workbook_set_custom_property_integer(lxw_workbook *workbook, const char *name, int32_t value);
|
||||
lxw_error LXW_CALL workbook_set_custom_property_boolean(lxw_workbook *workbook, const char *name, uint8_t value);
|
||||
lxw_error LXW_CALL workbook_set_custom_property_datetime(lxw_workbook *workbook, const char *name, lxw_datetime *datetime);
|
||||
lxw_error LXW_CALL workbook_define_name(lxw_workbook *workbook, const char *name, const char *formula);
|
||||
lxw_format * LXW_CALL workbook_get_default_url_format(lxw_workbook *workbook);
|
||||
lxw_worksheet * LXW_CALL workbook_get_worksheet_by_name(lxw_workbook *workbook, const char *name);
|
||||
lxw_chartsheet * LXW_CALL workbook_get_chartsheet_by_name(lxw_workbook *workbook, const char *name);
|
||||
lxw_error LXW_CALL workbook_validate_sheet_name(lxw_workbook *workbook, const char *sheetname);
|
||||
lxw_error LXW_CALL workbook_add_vba_project(lxw_workbook *workbook, const char *filename);
|
||||
lxw_error LXW_CALL workbook_add_signed_vba_project(lxw_workbook *workbook, const char *vba_project, const char *signature);
|
||||
lxw_error LXW_CALL workbook_set_vba_name(lxw_workbook *workbook, const char *name);
|
||||
void LXW_CALL workbook_read_only_recommended(lxw_workbook *workbook);
|
||||
void LXW_CALL workbook_use_1904_epoch(lxw_workbook *workbook);
|
||||
void LXW_CALL workbook_set_size(lxw_workbook *workbook, uint16_t width, uint16_t height);
|
||||
|
||||
/* ============================================================================
|
||||
* WORKSHEET FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
lxw_error LXW_CALL worksheet_write_number(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, double number, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_string(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *string, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_formula(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *formula, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_array_formula(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, const char *formula, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_dynamic_array_formula(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, const char *formula, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_dynamic_formula(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *formula, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_datetime(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_datetime *datetime, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_unixtime(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, int64_t unixtime, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_url(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *url, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_url_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *url, lxw_format *format, const char *string, const char *tooltip);
|
||||
lxw_error LXW_CALL worksheet_write_boolean(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, int value, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_blank(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_formula_num(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *formula, lxw_format *format, double result);
|
||||
lxw_error LXW_CALL worksheet_write_formula_str(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *formula, lxw_format *format, const char *result);
|
||||
lxw_error LXW_CALL worksheet_write_rich_string(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_rich_string_tuple *rich_string[], lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_write_comment(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *string);
|
||||
lxw_error LXW_CALL worksheet_write_comment_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *string, lxw_comment_options *options);
|
||||
|
||||
lxw_error LXW_CALL worksheet_set_row(lxw_worksheet *worksheet, lxw_row_t row, double height, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_set_row_opt(lxw_worksheet *worksheet, lxw_row_t row, double height, lxw_format *format, lxw_row_col_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_row_pixels(lxw_worksheet *worksheet, lxw_row_t row, uint32_t pixels, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_set_row_pixels_opt(lxw_worksheet *worksheet, lxw_row_t row, uint32_t pixels, lxw_format *format, lxw_row_col_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_column(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double width, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_set_column_opt(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, double width, lxw_format *format, lxw_row_col_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_column_pixels(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, uint32_t pixels, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_set_column_pixels_opt(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col, uint32_t pixels, lxw_format *format, lxw_row_col_options *options);
|
||||
|
||||
lxw_error LXW_CALL worksheet_insert_image(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *filename);
|
||||
lxw_error LXW_CALL worksheet_insert_image_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *filename, lxw_image_options *options);
|
||||
lxw_error LXW_CALL worksheet_insert_image_buffer(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const unsigned char *image_buffer, size_t image_size);
|
||||
lxw_error LXW_CALL worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const unsigned char *image_buffer, size_t image_size, lxw_image_options *options);
|
||||
lxw_error LXW_CALL worksheet_embed_image(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *filename);
|
||||
lxw_error LXW_CALL worksheet_embed_image_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const char *filename, lxw_image_options *options);
|
||||
lxw_error LXW_CALL worksheet_embed_image_buffer(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const unsigned char *image_buffer, size_t image_size);
|
||||
lxw_error LXW_CALL worksheet_embed_image_buffer_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, const unsigned char *image_buffer, size_t image_size, lxw_image_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_background(lxw_worksheet *worksheet, const char *filename);
|
||||
lxw_error LXW_CALL worksheet_set_background_buffer(lxw_worksheet *worksheet, const unsigned char *image_buffer, size_t image_size);
|
||||
|
||||
lxw_error LXW_CALL worksheet_insert_chart(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_chart *chart);
|
||||
lxw_error LXW_CALL worksheet_insert_chart_opt(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_chart *chart, lxw_chart_options *options);
|
||||
lxw_error LXW_CALL worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, const char *string, lxw_format *format);
|
||||
lxw_error LXW_CALL worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
lxw_error LXW_CALL worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col, lxw_filter_rule *rule);
|
||||
lxw_error LXW_CALL worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col, lxw_filter_rule *rule1, lxw_filter_rule *rule2, uint8_t and_or);
|
||||
lxw_error LXW_CALL worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col, const char **list);
|
||||
lxw_error LXW_CALL worksheet_data_validation_cell(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_data_validation *validation);
|
||||
lxw_error LXW_CALL worksheet_data_validation_range(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, lxw_data_validation *validation);
|
||||
lxw_error LXW_CALL worksheet_conditional_format_cell(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_conditional_format *conditional_format);
|
||||
lxw_error LXW_CALL worksheet_conditional_format_range(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, lxw_conditional_format *conditional_format);
|
||||
lxw_error LXW_CALL worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col, lxw_button_options *options);
|
||||
lxw_error LXW_CALL worksheet_add_table(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col, lxw_table_options *options);
|
||||
|
||||
void LXW_CALL worksheet_activate(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_select(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_hide(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_first_sheet(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_freeze_panes(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL worksheet_split_panes(lxw_worksheet *worksheet, double vertical, double horizontal);
|
||||
lxw_error LXW_CALL worksheet_set_selection(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL worksheet_set_top_left_cell(lxw_worksheet *worksheet, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL worksheet_set_landscape(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_portrait(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_page_view(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_paper(lxw_worksheet *worksheet, uint8_t paper_type);
|
||||
void LXW_CALL worksheet_set_margins(lxw_worksheet *worksheet, double left, double right, double top, double bottom);
|
||||
lxw_error LXW_CALL worksheet_set_header(lxw_worksheet *worksheet, const char *string);
|
||||
lxw_error LXW_CALL worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
|
||||
lxw_error LXW_CALL worksheet_set_header_opt(lxw_worksheet *worksheet, const char *string, lxw_header_footer_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_footer_opt(lxw_worksheet *worksheet, const char *string, lxw_header_footer_options *options);
|
||||
lxw_error LXW_CALL worksheet_set_h_pagebreaks(lxw_worksheet *worksheet, lxw_row_t breaks[]);
|
||||
lxw_error LXW_CALL worksheet_set_v_pagebreaks(lxw_worksheet *worksheet, lxw_col_t breaks[]);
|
||||
void LXW_CALL worksheet_print_across(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_zoom(lxw_worksheet *worksheet, uint16_t scale);
|
||||
void LXW_CALL worksheet_gridlines(lxw_worksheet *worksheet, uint8_t option);
|
||||
void LXW_CALL worksheet_center_horizontally(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_center_vertically(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_print_row_col_headers(lxw_worksheet *worksheet);
|
||||
lxw_error LXW_CALL worksheet_repeat_rows(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_row_t last_row);
|
||||
lxw_error LXW_CALL worksheet_repeat_columns(lxw_worksheet *worksheet, lxw_col_t first_col, lxw_col_t last_col);
|
||||
lxw_error LXW_CALL worksheet_print_area(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width, uint16_t height);
|
||||
void LXW_CALL worksheet_set_start_page(lxw_worksheet *worksheet, uint16_t start_page);
|
||||
void LXW_CALL worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
|
||||
void LXW_CALL worksheet_print_black_and_white(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_right_to_left(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_hide_zero(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
|
||||
void LXW_CALL worksheet_protect(lxw_worksheet *worksheet, const char *password, lxw_protection *options);
|
||||
void LXW_CALL worksheet_outline_settings(lxw_worksheet *worksheet, uint8_t visible, uint8_t symbols_below, uint8_t symbols_right, uint8_t auto_style);
|
||||
void LXW_CALL worksheet_set_default_row(lxw_worksheet *worksheet, double height, uint8_t hide_unused_rows);
|
||||
lxw_error LXW_CALL worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
|
||||
void LXW_CALL worksheet_show_comments(lxw_worksheet *worksheet);
|
||||
void LXW_CALL worksheet_set_comments_author(lxw_worksheet *worksheet, const char *author);
|
||||
lxw_error LXW_CALL worksheet_ignore_errors(lxw_worksheet *worksheet, uint8_t type, const char *range);
|
||||
|
||||
/* ============================================================================
|
||||
* CHARTSHEET FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
lxw_error LXW_CALL chartsheet_set_chart(lxw_chartsheet *chartsheet, lxw_chart *chart);
|
||||
lxw_error LXW_CALL chartsheet_set_chart_opt(lxw_chartsheet *chartsheet, lxw_chart *chart, lxw_chart_options *user_options);
|
||||
void LXW_CALL chartsheet_activate(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_select(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_hide(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_set_first_sheet(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_set_tab_color(lxw_chartsheet *chartsheet, lxw_color_t color);
|
||||
void LXW_CALL chartsheet_protect(lxw_chartsheet *chartsheet, const char *password, lxw_protection *options);
|
||||
void LXW_CALL chartsheet_set_zoom(lxw_chartsheet *chartsheet, uint16_t scale);
|
||||
void LXW_CALL chartsheet_set_landscape(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_set_portrait(lxw_chartsheet *chartsheet);
|
||||
void LXW_CALL chartsheet_set_paper(lxw_chartsheet *chartsheet, uint8_t paper_type);
|
||||
void LXW_CALL chartsheet_set_margins(lxw_chartsheet *chartsheet, double left, double right, double top, double bottom);
|
||||
lxw_error LXW_CALL chartsheet_set_header(lxw_chartsheet *chartsheet, const char *string);
|
||||
lxw_error LXW_CALL chartsheet_set_footer(lxw_chartsheet *chartsheet, const char *string);
|
||||
lxw_error LXW_CALL chartsheet_set_header_opt(lxw_chartsheet *chartsheet, const char *string, lxw_header_footer_options *options);
|
||||
lxw_error LXW_CALL chartsheet_set_footer_opt(lxw_chartsheet *chartsheet, const char *string, lxw_header_footer_options *options);
|
||||
|
||||
/* ============================================================================
|
||||
* CHART FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
lxw_chart_series * LXW_CALL chart_add_series(lxw_chart *chart, const char *categories, const char *values);
|
||||
lxw_chart_series * LXW_CALL chart_add_series_on_axis(lxw_chart *chart, const char *categories, const char *values, lxw_chart_axis *y_axis);
|
||||
|
||||
void LXW_CALL chart_series_set_categories(lxw_chart_series *series, const char *sheetname, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL chart_series_set_values(lxw_chart_series *series, const char *sheetname, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL chart_series_set_name(lxw_chart_series *series, const char *name);
|
||||
void LXW_CALL chart_series_set_name_range(lxw_chart_series *series, const char *sheetname, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL chart_series_set_line(lxw_chart_series *series, lxw_chart_line *line);
|
||||
void LXW_CALL chart_series_set_fill(lxw_chart_series *series, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_series_set_invert_if_negative(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_pattern(lxw_chart_series *series, lxw_chart_pattern *pattern);
|
||||
void LXW_CALL chart_series_set_marker_type(lxw_chart_series *series, uint8_t type);
|
||||
void LXW_CALL chart_series_set_marker_size(lxw_chart_series *series, uint8_t size);
|
||||
void LXW_CALL chart_series_set_marker_line(lxw_chart_series *series, lxw_chart_line *line);
|
||||
void LXW_CALL chart_series_set_marker_fill(lxw_chart_series *series, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_series_set_marker_pattern(lxw_chart_series *series, lxw_chart_pattern *pattern);
|
||||
lxw_error LXW_CALL chart_series_set_points(lxw_chart_series *series, lxw_chart_point *points[]);
|
||||
void LXW_CALL chart_series_set_smooth(lxw_chart_series *series, uint8_t smooth);
|
||||
void LXW_CALL chart_series_set_labels(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_labels_options(lxw_chart_series *series, uint8_t show_name, uint8_t show_category, uint8_t show_value);
|
||||
lxw_error LXW_CALL chart_series_set_labels_custom(lxw_chart_series *series, lxw_chart_data_label *data_labels[]);
|
||||
void LXW_CALL chart_series_set_labels_separator(lxw_chart_series *series, uint8_t separator);
|
||||
void LXW_CALL chart_series_set_labels_position(lxw_chart_series *series, uint8_t position);
|
||||
void LXW_CALL chart_series_set_labels_leader_line(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_labels_legend(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_labels_percentage(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_labels_num_format(lxw_chart_series *series, const char *num_format);
|
||||
void LXW_CALL chart_series_set_labels_font(lxw_chart_series *series, lxw_chart_font *font);
|
||||
void LXW_CALL chart_series_set_labels_line(lxw_chart_series *series, lxw_chart_line *line);
|
||||
void LXW_CALL chart_series_set_labels_fill(lxw_chart_series *series, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_series_set_labels_pattern(lxw_chart_series *series, lxw_chart_pattern *pattern);
|
||||
void LXW_CALL chart_series_set_trendline(lxw_chart_series *series, uint8_t type, uint8_t value);
|
||||
void LXW_CALL chart_series_set_trendline_forecast(lxw_chart_series *series, double forward, double backward);
|
||||
void LXW_CALL chart_series_set_trendline_equation(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_trendline_r_squared(lxw_chart_series *series);
|
||||
void LXW_CALL chart_series_set_trendline_intercept(lxw_chart_series *series, double intercept);
|
||||
void LXW_CALL chart_series_set_trendline_name(lxw_chart_series *series, const char *name);
|
||||
void LXW_CALL chart_series_set_trendline_line(lxw_chart_series *series, lxw_chart_line *line);
|
||||
void LXW_CALL chart_series_set_error_bars(lxw_series_error_bars *error_bars, uint8_t type, double value);
|
||||
void LXW_CALL chart_series_set_error_bars_direction(lxw_series_error_bars *error_bars, uint8_t direction);
|
||||
void LXW_CALL chart_series_set_error_bars_endcap(lxw_series_error_bars *error_bars, uint8_t endcap);
|
||||
void LXW_CALL chart_series_set_error_bars_line(lxw_series_error_bars *error_bars, lxw_chart_line *line);
|
||||
|
||||
void LXW_CALL chart_axis_set_name(lxw_chart_axis *axis, const char *name);
|
||||
void LXW_CALL chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL chart_axis_set_name_layout(lxw_chart_axis *axis, lxw_chart_layout *layout);
|
||||
void LXW_CALL chart_axis_set_name_font(lxw_chart_axis *axis, lxw_chart_font *font);
|
||||
void LXW_CALL chart_axis_set_num_font(lxw_chart_axis *axis, lxw_chart_font *font);
|
||||
void LXW_CALL chart_axis_set_num_format(lxw_chart_axis *axis, const char *num_format);
|
||||
void LXW_CALL chart_axis_set_line(lxw_chart_axis *axis, lxw_chart_line *line);
|
||||
void LXW_CALL chart_axis_set_fill(lxw_chart_axis *axis, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_axis_set_pattern(lxw_chart_axis *axis, lxw_chart_pattern *pattern);
|
||||
void LXW_CALL chart_axis_set_reverse(lxw_chart_axis *axis);
|
||||
void LXW_CALL chart_axis_set_crossing(lxw_chart_axis *axis, double value);
|
||||
void LXW_CALL chart_axis_set_crossing_max(lxw_chart_axis *axis);
|
||||
void LXW_CALL chart_axis_set_crossing_min(lxw_chart_axis *axis);
|
||||
void LXW_CALL chart_axis_off(lxw_chart_axis *axis);
|
||||
void LXW_CALL chart_axis_set_position(lxw_chart_axis *axis, uint8_t position);
|
||||
void LXW_CALL chart_axis_set_label_position(lxw_chart_axis *axis, uint8_t position);
|
||||
void LXW_CALL chart_axis_set_label_align(lxw_chart_axis *axis, uint8_t align);
|
||||
void LXW_CALL chart_axis_set_min(lxw_chart_axis *axis, double min);
|
||||
void LXW_CALL chart_axis_set_max(lxw_chart_axis *axis, double max);
|
||||
void LXW_CALL chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base);
|
||||
void LXW_CALL chart_axis_set_major_tick_mark(lxw_chart_axis *axis, uint8_t type);
|
||||
void LXW_CALL chart_axis_set_minor_tick_mark(lxw_chart_axis *axis, uint8_t type);
|
||||
void LXW_CALL chart_axis_set_interval_unit(lxw_chart_axis *axis, uint16_t unit);
|
||||
void LXW_CALL chart_axis_set_interval_tick(lxw_chart_axis *axis, uint16_t unit);
|
||||
void LXW_CALL chart_axis_set_major_unit(lxw_chart_axis *axis, double unit);
|
||||
void LXW_CALL chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit);
|
||||
void LXW_CALL chart_axis_set_display_units(lxw_chart_axis *axis, uint8_t units);
|
||||
void LXW_CALL chart_axis_set_display_units_visible(lxw_chart_axis *axis, uint8_t visible);
|
||||
void LXW_CALL chart_axis_major_gridlines_set_visible(lxw_chart_axis *axis, uint8_t visible);
|
||||
void LXW_CALL chart_axis_minor_gridlines_set_visible(lxw_chart_axis *axis, uint8_t visible);
|
||||
void LXW_CALL chart_axis_major_gridlines_set_line(lxw_chart_axis *axis, lxw_chart_line *line);
|
||||
void LXW_CALL chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis, lxw_chart_line *line);
|
||||
|
||||
void LXW_CALL chart_title_set_name(lxw_chart *chart, const char *name);
|
||||
void LXW_CALL chart_title_set_name_range(lxw_chart *chart, const char *sheetname, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL chart_title_set_name_font(lxw_chart *chart, lxw_chart_font *font);
|
||||
void LXW_CALL chart_title_off(lxw_chart *chart);
|
||||
void LXW_CALL chart_title_set_layout(lxw_chart *chart, lxw_chart_layout *layout);
|
||||
void LXW_CALL chart_title_set_overlay(lxw_chart *chart, uint8_t overlay);
|
||||
void LXW_CALL chart_legend_set_position(lxw_chart *chart, uint8_t position);
|
||||
void LXW_CALL chart_legend_set_layout(lxw_chart *chart, lxw_chart_layout *layout);
|
||||
void LXW_CALL chart_legend_set_font(lxw_chart *chart, lxw_chart_font *font);
|
||||
lxw_error LXW_CALL chart_legend_delete_series(lxw_chart *chart, int16_t delete_series[]);
|
||||
void LXW_CALL chart_chartarea_set_line(lxw_chart *chart, lxw_chart_line *line);
|
||||
void LXW_CALL chart_chartarea_set_fill(lxw_chart *chart, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_chartarea_set_pattern(lxw_chart *chart, lxw_chart_pattern *pattern);
|
||||
void LXW_CALL chart_plotarea_set_line(lxw_chart *chart, lxw_chart_line *line);
|
||||
void LXW_CALL chart_plotarea_set_fill(lxw_chart *chart, lxw_chart_fill *fill);
|
||||
void LXW_CALL chart_plotarea_set_pattern(lxw_chart *chart, lxw_chart_pattern *pattern);
|
||||
void LXW_CALL chart_plotarea_set_layout(lxw_chart *chart, lxw_chart_layout *layout);
|
||||
void LXW_CALL chart_set_style(lxw_chart *chart, uint8_t style_id);
|
||||
void LXW_CALL chart_set_table(lxw_chart *chart);
|
||||
void LXW_CALL chart_set_table_grid(lxw_chart *chart, uint8_t horizontal, uint8_t vertical, uint8_t outline, uint8_t legend_keys);
|
||||
void LXW_CALL chart_set_table_font(lxw_chart *chart, lxw_chart_font *font);
|
||||
void LXW_CALL chart_set_up_down_bars(lxw_chart *chart);
|
||||
void LXW_CALL chart_set_up_down_bars_format(lxw_chart *chart, lxw_chart_line *up_bar_line, lxw_chart_fill *up_bar_fill, lxw_chart_line *down_bar_line, lxw_chart_fill *down_bar_fill);
|
||||
void LXW_CALL chart_set_drop_lines(lxw_chart *chart, lxw_chart_line *line);
|
||||
void LXW_CALL chart_set_high_low_lines(lxw_chart *chart, lxw_chart_line *line);
|
||||
void LXW_CALL chart_set_series_overlap(lxw_chart *chart, int8_t overlap);
|
||||
void LXW_CALL chart_set_series_gap(lxw_chart *chart, uint16_t gap);
|
||||
void LXW_CALL chart_show_blanks_as(lxw_chart *chart, uint8_t option);
|
||||
void LXW_CALL chart_show_hidden_data(lxw_chart *chart);
|
||||
void LXW_CALL chart_set_rotation(lxw_chart *chart, uint16_t rotation);
|
||||
void LXW_CALL chart_set_hole_size(lxw_chart *chart, uint8_t size);
|
||||
|
||||
/* ============================================================================
|
||||
* FORMAT FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
void LXW_CALL format_set_font_name(lxw_format *format, const char *font_name);
|
||||
void LXW_CALL format_set_font_size(lxw_format *format, double size);
|
||||
void LXW_CALL format_set_font_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_bold(lxw_format *format);
|
||||
void LXW_CALL format_set_italic(lxw_format *format);
|
||||
void LXW_CALL format_set_underline(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_font_strikeout(lxw_format *format);
|
||||
void LXW_CALL format_set_font_script(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_font_family(lxw_format *format, uint8_t value);
|
||||
void LXW_CALL format_set_font_charset(lxw_format *format, uint8_t value);
|
||||
void LXW_CALL format_set_num_format(lxw_format *format, const char *num_format);
|
||||
void LXW_CALL format_set_num_format_index(lxw_format *format, uint8_t index);
|
||||
void LXW_CALL format_set_unlocked(lxw_format *format);
|
||||
void LXW_CALL format_set_hidden(lxw_format *format);
|
||||
void LXW_CALL format_set_align(lxw_format *format, uint8_t alignment);
|
||||
void LXW_CALL format_set_text_wrap(lxw_format *format);
|
||||
void LXW_CALL format_set_rotation(lxw_format *format, int16_t angle);
|
||||
void LXW_CALL format_set_indent(lxw_format *format, uint8_t level);
|
||||
void LXW_CALL format_set_shrink(lxw_format *format);
|
||||
void LXW_CALL format_set_pattern(lxw_format *format, uint8_t index);
|
||||
void LXW_CALL format_set_bg_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_fg_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_border(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_bottom(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_top(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_left(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_right(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_border_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_bottom_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_top_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_left_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_right_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_diag_type(lxw_format *format, uint8_t type);
|
||||
void LXW_CALL format_set_diag_border(lxw_format *format, uint8_t style);
|
||||
void LXW_CALL format_set_diag_color(lxw_format *format, lxw_color_t color);
|
||||
void LXW_CALL format_set_quote_prefix(lxw_format *format);
|
||||
|
||||
/* ============================================================================
|
||||
* UTILITY FUNCTIONS
|
||||
* ============================================================================ */
|
||||
|
||||
const char * LXW_CALL lxw_version(void);
|
||||
uint16_t LXW_CALL lxw_version_id(void);
|
||||
char * LXW_CALL lxw_strerror(lxw_error error_num);
|
||||
|
||||
void LXW_CALL lxw_col_to_name(char *col_name, lxw_col_t col_num, uint8_t absolute);
|
||||
void LXW_CALL lxw_rowcol_to_cell(char *cell_name, lxw_row_t row, lxw_col_t col);
|
||||
void LXW_CALL lxw_rowcol_to_cell_abs(char *cell_name, lxw_row_t row, lxw_col_t col, uint8_t abs_row, uint8_t abs_col);
|
||||
void LXW_CALL lxw_rowcol_to_range(char *range, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL lxw_rowcol_to_range_abs(char *range, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
void LXW_CALL lxw_rowcol_to_formula_abs(char *formula, const char *sheetname, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col);
|
||||
|
||||
uint32_t LXW_CALL lxw_name_to_row(const char *row_str);
|
||||
uint16_t LXW_CALL lxw_name_to_col(const char *col_str);
|
||||
uint32_t LXW_CALL lxw_name_to_row_2(const char *row_str);
|
||||
uint16_t LXW_CALL lxw_name_to_col_2(const char *col_str);
|
||||
|
||||
double LXW_CALL lxw_datetime_to_excel_datetime(lxw_datetime *datetime);
|
||||
double LXW_CALL lxw_datetime_to_excel_date_with_epoch(lxw_datetime *datetime, uint8_t use_1904_epoch);
|
||||
double LXW_CALL lxw_unixtime_to_excel_date(int64_t unixtime);
|
||||
double LXW_CALL lxw_unixtime_to_excel_date_with_epoch(int64_t unixtime, uint8_t use_1904_epoch);
|
||||
|
||||
/* ============================================================================
|
||||
* MACRO REPLACEMENT FUNCTIONS
|
||||
*
|
||||
* The following inline functions replace the original macros:
|
||||
* - CELL(cell) -> use lxw_name_to_row(cell) and lxw_name_to_col(cell) separately
|
||||
* - COLS(cols) -> use lxw_name_to_col(cols) and lxw_name_to_col_2(cols) separately
|
||||
* - RANGE(range) -> use lxw_name_to_row(range), lxw_name_to_col(range),
|
||||
* lxw_name_to_row_2(range), lxw_name_to_col_2(range) separately
|
||||
*
|
||||
* Example usage:
|
||||
* Instead of: worksheet_write_string(worksheet, CELL("A1"), "Hello", NULL);
|
||||
* Use: worksheet_write_string(worksheet, lxw_name_to_row("A1"),
|
||||
* lxw_name_to_col("A1"), "Hello", NULL);
|
||||
*
|
||||
* Instead of: worksheet_set_column(worksheet, COLS("B:D"), 20, NULL, NULL);
|
||||
* Use: worksheet_set_column(worksheet, lxw_name_to_col("B:D"),
|
||||
* lxw_name_to_col_2("B:D"), 20, NULL, NULL);
|
||||
*
|
||||
* Instead of: worksheet_print_area(worksheet, RANGE("A1:K42"));
|
||||
* Use: worksheet_print_area(worksheet, lxw_name_to_row("A1:K42"),
|
||||
* lxw_name_to_col("A1:K42"),
|
||||
* lxw_name_to_row_2("A1:K42"),
|
||||
* lxw_name_to_col_2("A1:K42"));
|
||||
* ============================================================================ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIBXLSXWRITER_LV_H__ */
|
||||
911
src/chart.c
911
src/chart.c
File diff suppressed because it is too large
Load diff
|
|
@ -314,6 +314,24 @@ lxw_ct_add_chart_name(lxw_content_types *self, const char *name)
|
|||
lxw_ct_add_override(self, name, LXW_APP_DOCUMENT "drawingml.chart+xml");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the name of a chart style to the ContentTypes overrides.
|
||||
*/
|
||||
void
|
||||
lxw_ct_add_chart_style_name(lxw_content_types *self, const char *name)
|
||||
{
|
||||
lxw_ct_add_override(self, name, "application/vnd.ms-office.chartstyle+xml");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the name of a chart color style to the ContentTypes overrides.
|
||||
*/
|
||||
void
|
||||
lxw_ct_add_chart_colors_name(lxw_content_types *self, const char *name)
|
||||
{
|
||||
lxw_ct_add_override(self, name, "application/vnd.ms-office.chartcolorstyle+xml");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the name of a drawing to the ContentTypes overrides.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -247,15 +247,25 @@ _drawing_write_a_hlink_click(lxw_drawing *self, uint32_t rel_index, char *tip)
|
|||
* Write the <a16:creationId> element.
|
||||
*/
|
||||
STATIC void
|
||||
_drawing_write_a16_creation_id(lxw_drawing *self)
|
||||
_drawing_write_a16_creation_id(lxw_drawing *self, uint32_t index)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
char xmlns[] = "http://schemas.microsoft.com/office/drawing/2014/main";
|
||||
char guid[LXW_GUID_LENGTH];
|
||||
|
||||
/* Generate a pseudo-GUID based on the index. */
|
||||
lxw_snprintf(guid, LXW_GUID_LENGTH,
|
||||
"{%08X-%04X-%04X-%04X-%012lX}",
|
||||
(unsigned int)(0xCC148400 + index),
|
||||
(unsigned int)0xB16C,
|
||||
(unsigned int)0x9B21,
|
||||
(unsigned int)0xA699,
|
||||
(unsigned long)(0xF10CC9149C00UL + index));
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_STR("xmlns:a16", xmlns);
|
||||
LXW_PUSH_ATTRIBUTES_STR("id", "{00000000-0008-0000-0000-000002000000}");
|
||||
LXW_PUSH_ATTRIBUTES_STR("id", guid);
|
||||
|
||||
lxw_xml_empty_tag(self->file, "a16:creationId", &attributes);
|
||||
|
||||
|
|
@ -303,12 +313,12 @@ _drawing_write_uri_ext(lxw_drawing *self, char *uri)
|
|||
* Write the decorative elements.
|
||||
*/
|
||||
STATIC void
|
||||
_workbook_write_decorative(lxw_drawing *self)
|
||||
_workbook_write_decorative(lxw_drawing *self, uint32_t index)
|
||||
{
|
||||
lxw_xml_start_tag(self->file, "a:extLst", NULL);
|
||||
|
||||
_drawing_write_uri_ext(self, "{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}");
|
||||
_drawing_write_a16_creation_id(self);
|
||||
_drawing_write_a16_creation_id(self, index);
|
||||
lxw_xml_end_tag(self->file, "a:ext");
|
||||
|
||||
_drawing_write_uri_ext(self, "{C183D7F6-B498-43B3-948B-1728B52AA6E4}");
|
||||
|
|
@ -318,6 +328,21 @@ _workbook_write_decorative(lxw_drawing *self)
|
|||
lxw_xml_end_tag(self->file, "a:extLst");
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the creation ID extension list for charts.
|
||||
*/
|
||||
STATIC void
|
||||
_drawing_write_chart_creation_id(lxw_drawing *self, uint32_t index)
|
||||
{
|
||||
lxw_xml_start_tag(self->file, "a:extLst", NULL);
|
||||
|
||||
_drawing_write_uri_ext(self, "{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}");
|
||||
_drawing_write_a16_creation_id(self, index);
|
||||
lxw_xml_end_tag(self->file, "a:ext");
|
||||
|
||||
lxw_xml_end_tag(self->file, "a:extLst");
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <xdr:cNvPr> element.
|
||||
*/
|
||||
|
|
@ -355,11 +380,17 @@ _drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint32_t index,
|
|||
}
|
||||
|
||||
if (drawing_object->decorative) {
|
||||
_workbook_write_decorative(self);
|
||||
_workbook_write_decorative(self, index);
|
||||
}
|
||||
|
||||
lxw_xml_end_tag(self->file, "xdr:cNvPr");
|
||||
}
|
||||
else if (strcmp(object_name, "Chart") == 0) {
|
||||
/* Charts need creation ID extension list. */
|
||||
lxw_xml_start_tag(self->file, "xdr:cNvPr", &attributes);
|
||||
_drawing_write_chart_creation_id(self, index);
|
||||
lxw_xml_end_tag(self->file, "xdr:cNvPr");
|
||||
}
|
||||
else {
|
||||
lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
|
||||
}
|
||||
|
|
|
|||
19
src/format.c
19
src/format.c
|
|
@ -546,12 +546,6 @@ format_set_text_justlast(lxw_format *self)
|
|||
void
|
||||
format_set_pattern(lxw_format *self, uint8_t value)
|
||||
{
|
||||
if (value > LXW_PATTERN_GRAY_0625) {
|
||||
LXW_WARN_FORMAT1("format_set_pattern(): invalid pattern value: %d",
|
||||
value);
|
||||
return;
|
||||
}
|
||||
|
||||
self->pattern = value;
|
||||
}
|
||||
|
||||
|
|
@ -695,12 +689,6 @@ format_set_diag_color(lxw_format *self, lxw_color_t color)
|
|||
void
|
||||
format_set_diag_border(lxw_format *self, uint8_t style)
|
||||
{
|
||||
if (style > LXW_BORDER_SLANT_DASH_DOT) {
|
||||
LXW_WARN_FORMAT1("format_set_diag_border(): invalid border style: %d",
|
||||
style);
|
||||
return;
|
||||
}
|
||||
|
||||
self->diag_border = style;
|
||||
}
|
||||
|
||||
|
|
@ -719,13 +707,6 @@ format_set_num_format_index(lxw_format *self, uint8_t value)
|
|||
void
|
||||
format_set_valign(lxw_format *self, uint8_t value)
|
||||
{
|
||||
if (value > LXW_ALIGN_VERTICAL_DISTRIBUTED) {
|
||||
LXW_WARN_FORMAT1
|
||||
("format_set_valign(): invalid vertical alignment value: %d",
|
||||
value);
|
||||
return;
|
||||
}
|
||||
|
||||
self->text_v_align = value;
|
||||
}
|
||||
|
||||
|
|
|
|||
236
src/packager.c
236
src/packager.c
|
|
@ -549,6 +549,175 @@ _write_chart_files(lxw_packager *self)
|
|||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the chart style files for charts.
|
||||
*/
|
||||
STATIC lxw_error
|
||||
_write_chart_style_files(lxw_packager *self)
|
||||
{
|
||||
lxw_workbook *workbook = self->workbook;
|
||||
lxw_chart *chart;
|
||||
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
||||
uint32_t index = 1;
|
||||
lxw_error err;
|
||||
|
||||
/* Complete chart style XML content (based on Excel's default style 240) - from working file */
|
||||
const char *style_xml =
|
||||
"<cs:chartStyle xmlns:cs=\"http://schemas.microsoft.com/office/drawing/2012/chartStyle\" "
|
||||
"xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" id=\"240\">"
|
||||
"<cs:axisTitle><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"1000\" kern=\"1200\"/></cs:axisTitle>"
|
||||
"<cs:categoryAxis><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"25000\"/><a:lumOff val=\"75000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:categoryAxis>"
|
||||
"<cs:chartArea mods=\"allowNoFillOverride allowNoLineOverride\"><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef>"
|
||||
"<cs:spPr><a:solidFill><a:schemeClr val=\"bg1\"/></a:solidFill>"
|
||||
"<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"15000\"/><a:lumOff val=\"85000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr>"
|
||||
"<cs:defRPr sz=\"1000\" kern=\"1200\"/></cs:chartArea>"
|
||||
"<cs:dataLabel><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"75000\"/><a:lumOff val=\"25000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:dataLabel>"
|
||||
"<cs:dataLabelCallout><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"dk1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:spPr><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill><a:ln><a:solidFill><a:schemeClr val=\"dk1\">"
|
||||
"<a:lumMod val=\"25000\"/><a:lumOff val=\"75000\"/></a:schemeClr></a:solidFill></a:ln></cs:spPr>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/><cs:bodyPr rot=\"0\" spcFirstLastPara=\"1\" vertOverflow=\"clip\" horzOverflow=\"clip\" vert=\"horz\" wrap=\"square\" lIns=\"36576\" tIns=\"18288\" rIns=\"36576\" bIns=\"18288\" anchor=\"ctr\" anchorCtr=\"1\"><a:spAutoFit/></cs:bodyPr></cs:dataLabelCallout>"
|
||||
"<cs:dataPoint><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"1\"><cs:styleClr val=\"auto\"/></cs:fillRef>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef></cs:dataPoint>"
|
||||
"<cs:dataPoint3D><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"1\"><cs:styleClr val=\"auto\"/></cs:fillRef>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef></cs:dataPoint3D>"
|
||||
"<cs:dataPointLine><cs:lnRef idx=\"0\"><cs:styleClr val=\"auto\"/></cs:lnRef><cs:fillRef idx=\"1\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"19050\" cap=\"rnd\"><a:solidFill>"
|
||||
"<a:schemeClr val=\"phClr\"/></a:solidFill><a:round/></a:ln></cs:spPr></cs:dataPointLine>"
|
||||
"<cs:dataPointMarker><cs:lnRef idx=\"0\"><cs:styleClr val=\"auto\"/></cs:lnRef><cs:fillRef idx=\"1\"><cs:styleClr val=\"auto\"/></cs:fillRef>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef>"
|
||||
"<cs:spPr><a:ln w=\"9525\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln></cs:spPr></cs:dataPointMarker>"
|
||||
"<cs:dataPointMarkerLayout symbol=\"circle\" size=\"5\"/>"
|
||||
"<cs:dataPointWireframe><cs:lnRef idx=\"0\"><cs:styleClr val=\"auto\"/></cs:lnRef><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"dk1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"rnd\"><a:solidFill>"
|
||||
"<a:schemeClr val=\"phClr\"/></a:solidFill><a:round/></a:ln></cs:spPr></cs:dataPointWireframe>"
|
||||
"<cs:dataTable><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:spPr><a:noFill/><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"15000\"/><a:lumOff val=\"85000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:dataTable>"
|
||||
"<cs:downBar><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:solidFill><a:schemeClr val=\"dk1\">"
|
||||
"<a:lumMod val=\"75000\"/><a:lumOff val=\"25000\"/></a:schemeClr></a:solidFill>"
|
||||
"<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:downBar>"
|
||||
"<cs:dropLine><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"35000\"/><a:lumOff val=\"65000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:dropLine>"
|
||||
"<cs:errorBar><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:errorBar>"
|
||||
"<cs:floor><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:noFill/><a:ln><a:noFill/></a:ln></cs:spPr></cs:floor>"
|
||||
"<cs:gridlineMajor><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef>"
|
||||
"<cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"15000\"/><a:lumOff val=\"85000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:gridlineMajor>"
|
||||
"<cs:gridlineMinor><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"5000\"/><a:lumOff val=\"95000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:gridlineMinor>"
|
||||
"<cs:hiLoLine><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"50000\"/><a:lumOff val=\"50000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:hiLoLine>"
|
||||
"<cs:leaderLine><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"35000\"/><a:lumOff val=\"65000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:leaderLine>"
|
||||
"<cs:legend><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:legend>"
|
||||
"<cs:plotArea mods=\"allowNoFillOverride allowNoLineOverride\"><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef></cs:plotArea>"
|
||||
"<cs:plotArea3D mods=\"allowNoFillOverride allowNoLineOverride\"><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/>"
|
||||
"<cs:effectRef idx=\"0\"/><cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef></cs:plotArea3D>"
|
||||
"<cs:seriesAxis><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:seriesAxis>"
|
||||
"<cs:seriesLine><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">"
|
||||
"<a:solidFill><a:schemeClr val=\"tx1\"><a:lumMod val=\"35000\"/><a:lumOff val=\"65000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:seriesLine>"
|
||||
"<cs:title><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"1400\" b=\"0\" kern=\"1200\" spc=\"0\" baseline=\"0\"/></cs:title>"
|
||||
"<cs:trendline><cs:lnRef idx=\"0\"><cs:styleClr val=\"auto\"/></cs:lnRef><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:ln w=\"19050\" cap=\"rnd\"><a:solidFill>"
|
||||
"<a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"sysDot\"/></a:ln></cs:spPr></cs:trendline>"
|
||||
"<cs:trendlineLabel><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:trendlineLabel>"
|
||||
"<cs:upBar><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:solidFill><a:schemeClr val=\"lt1\"/></a:solidFill>"
|
||||
"<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr></cs:upBar>"
|
||||
"<cs:valueAxis><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"><a:lumMod val=\"65000\"/><a:lumOff val=\"35000\"/></a:schemeClr></cs:fontRef>"
|
||||
"<cs:spPr><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"tx1\">"
|
||||
"<a:lumMod val=\"25000\"/><a:lumOff val=\"75000\"/></a:schemeClr></a:solidFill><a:round/></a:ln></cs:spPr>"
|
||||
"<cs:defRPr sz=\"900\" kern=\"1200\"/></cs:valueAxis>"
|
||||
"<cs:wall><cs:lnRef idx=\"0\"/><cs:fillRef idx=\"0\"/><cs:effectRef idx=\"0\"/>"
|
||||
"<cs:fontRef idx=\"minor\"><a:schemeClr val=\"tx1\"/></cs:fontRef><cs:spPr><a:noFill/><a:ln><a:noFill/></a:ln></cs:spPr></cs:wall>"
|
||||
"</cs:chartStyle>";
|
||||
|
||||
STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
|
||||
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
||||
"xl/charts/style%d.xml", index++);
|
||||
|
||||
err = _add_buffer_to_zip(self, style_xml, strlen(style_xml), filename);
|
||||
RETURN_ON_ERROR(err);
|
||||
}
|
||||
|
||||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the chart color files for charts.
|
||||
*/
|
||||
STATIC lxw_error
|
||||
_write_chart_color_files(lxw_packager *self)
|
||||
{
|
||||
lxw_workbook *workbook = self->workbook;
|
||||
lxw_chart *chart;
|
||||
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
||||
uint32_t index = 1;
|
||||
lxw_error err;
|
||||
|
||||
/* Static chart color style XML content (based on Excel's default color scheme 10) */
|
||||
const char *colors_xml =
|
||||
"<cs:colorStyle xmlns:cs=\"http://schemas.microsoft.com/office/drawing/2012/chartStyle\" "
|
||||
"xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" meth=\"cycle\" id=\"10\">"
|
||||
"<a:schemeClr val=\"accent1\"/><a:schemeClr val=\"accent2\"/><a:schemeClr val=\"accent3\"/>"
|
||||
"<a:schemeClr val=\"accent4\"/><a:schemeClr val=\"accent5\"/><a:schemeClr val=\"accent6\"/>"
|
||||
"<cs:variation/>"
|
||||
"<cs:variation><a:lumMod val=\"60000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"80000\"/><a:lumOff val=\"20000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"80000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"60000\"/><a:lumOff val=\"40000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"50000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"70000\"/><a:lumOff val=\"30000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"70000\"/></cs:variation>"
|
||||
"<cs:variation><a:lumMod val=\"50000\"/><a:lumOff val=\"50000\"/></cs:variation>"
|
||||
"</cs:colorStyle>";
|
||||
|
||||
STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
|
||||
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
||||
"xl/charts/colors%d.xml", index++);
|
||||
|
||||
err = _add_buffer_to_zip(self, colors_xml, strlen(colors_xml), filename);
|
||||
RETURN_ON_ERROR(err);
|
||||
}
|
||||
|
||||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the chart files.
|
||||
*/
|
||||
|
|
@ -1504,6 +1673,16 @@ _write_content_types_file(lxw_packager *self)
|
|||
lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/chart%d.xml",
|
||||
index);
|
||||
lxw_ct_add_chart_name(content_types, filename);
|
||||
|
||||
/* Register external style files (testing individually) */
|
||||
lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/style%d.xml",
|
||||
index);
|
||||
lxw_ct_add_chart_style_name(content_types, filename);
|
||||
|
||||
/* Register external color files (testing individually) */
|
||||
lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/colors%d.xml",
|
||||
index);
|
||||
lxw_ct_add_chart_colors_name(content_types, filename);
|
||||
}
|
||||
|
||||
for (index = 1; index <= drawing_count; index++) {
|
||||
|
|
@ -1843,6 +2022,51 @@ _write_drawing_rels_file(lxw_packager *self)
|
|||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the chart .rels files for charts that contain style and color references.
|
||||
*/
|
||||
STATIC lxw_error
|
||||
_write_chart_rels_files(lxw_packager *self)
|
||||
{
|
||||
lxw_relationships *rels;
|
||||
char *buffer = NULL;
|
||||
size_t buffer_size = 0;
|
||||
lxw_workbook *workbook = self->workbook;
|
||||
lxw_chart *chart;
|
||||
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
||||
uint32_t index = 1;
|
||||
lxw_error err;
|
||||
|
||||
STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
|
||||
rels = lxw_relationships_new();
|
||||
|
||||
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
||||
if (!rels->file) {
|
||||
lxw_free_relationships(rels);
|
||||
return LXW_ERROR_CREATING_TMPFILE;
|
||||
}
|
||||
|
||||
/* Add relationships to chart style and color files */
|
||||
lxw_add_chart_style_relationship(rels);
|
||||
lxw_add_chart_color_relationship(rels);
|
||||
|
||||
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
||||
"xl/charts/_rels/chart%d.xml.rels", index++);
|
||||
|
||||
lxw_relationships_assemble_xml_file(rels);
|
||||
|
||||
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, filename);
|
||||
|
||||
fclose(rels->file);
|
||||
free(buffer);
|
||||
lxw_free_relationships(rels);
|
||||
|
||||
RETURN_ON_ERROR(err);
|
||||
}
|
||||
|
||||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the vmlDrawing .rels files for worksheets that contain images in
|
||||
* headers or footers.
|
||||
|
|
@ -2187,6 +2411,14 @@ lxw_create_package(lxw_packager *self)
|
|||
error = _write_chart_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
/* Generate external style files (testing individually) */
|
||||
error = _write_chart_style_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
/* Generate external color files (testing individually) */
|
||||
error = _write_chart_color_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
error = _write_drawing_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
|
|
@ -2220,6 +2452,10 @@ lxw_create_package(lxw_packager *self)
|
|||
error = _write_drawing_rels_file(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
/* Generate chart relationship files (links to style/color files) */
|
||||
error = _write_chart_rels_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
error = _write_image_files(self);
|
||||
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
||||
|
||||
|
|
|
|||
|
|
@ -245,6 +245,25 @@ lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
|
|||
_add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, target_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add chart style and color relationships to chart .rels xml files.
|
||||
*/
|
||||
void
|
||||
lxw_add_chart_style_relationship(lxw_relationships *self)
|
||||
{
|
||||
_add_relationship(self,
|
||||
"http://schemas.microsoft.com/office/2011/relationships/",
|
||||
"chartStyle", "style1.xml", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
lxw_add_chart_color_relationship(lxw_relationships *self)
|
||||
{
|
||||
_add_relationship(self,
|
||||
"http://schemas.microsoft.com/office/2011/relationships/",
|
||||
"chartColorStyle", "colors1.xml", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a richValue relationship to sheet .rels xml files.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ char *error_strings[LXW_MAX_ERRNO + 1] = {
|
|||
"NULL function parameter ignored.",
|
||||
"Function parameter validation error.",
|
||||
"Function string parameter is empty.",
|
||||
"Datetime struct parameter has an invalid field value.",
|
||||
"Worksheet name exceeds Excel's limit of 31 characters.",
|
||||
"Worksheet name cannot contain invalid characters: '[ ] : * ? / \\'",
|
||||
"Worksheet name cannot start or end with an apostrophe.",
|
||||
|
|
@ -333,69 +332,6 @@ lxw_name_to_col_2(const char *col_str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
lxw_error
|
||||
lxw_datetime_validate(lxw_datetime *datetime)
|
||||
{
|
||||
if (!datetime)
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
|
||||
/*
|
||||
* Excel uses the year 1900 as the default epoch but it uses 1899-12-31 as
|
||||
* the 0 date and internally we use the 0-0-0 date for time only values.
|
||||
*/
|
||||
if (datetime->year < 1900 &&
|
||||
!(datetime->year == 0 &&
|
||||
datetime->month == 0 && datetime->day == 0) &&
|
||||
!(datetime->year == 1899 &&
|
||||
datetime->month == 12 && datetime->day == 31)) {
|
||||
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid year: %d. "
|
||||
"Valid range is 1900-9999.", datetime->year);
|
||||
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
if (datetime->year > 9999) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid year: %d. "
|
||||
"Valid range is 1900-9999.", datetime->year);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
if (datetime->year != 0) {
|
||||
if (datetime->month < 1 || datetime->month > 12) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid month: %d. "
|
||||
"Valid range is 1-12.", datetime->month);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
if (datetime->day < 1 || datetime->day > 31) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid day: %d. "
|
||||
"Valid range is 1-31.", datetime->day);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (datetime->hour < 0 || datetime->hour > 23) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid hour: %d. "
|
||||
"Valid range is 0-23.", datetime->hour);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
if (datetime->min < 0 || datetime->min > 59) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid minute: %d. "
|
||||
"Valid range is 0-59.", datetime->min);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
if (datetime->sec < 0.0 || datetime->sec >= 60.0) {
|
||||
LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid seconds: %.3f. "
|
||||
"Valid range is 0.0-59.999.", datetime->sec);
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
return LXW_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a lxw_datetime struct to an Excel serial date, with a 1900
|
||||
* or 1904 epoch.
|
||||
|
|
@ -421,9 +357,6 @@ lxw_datetime_to_excel_date_with_epoch(lxw_datetime *datetime,
|
|||
int days = 0;
|
||||
int i;
|
||||
|
||||
if (lxw_datetime_validate(datetime) != LXW_NO_ERROR)
|
||||
return 0.0;
|
||||
|
||||
/* For times without dates set the default date for the epoch. */
|
||||
if (!year) {
|
||||
if (!use_1904_epoch) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "xlsxwriter/utility.h"
|
||||
#include "xlsxwriter/packager.h"
|
||||
#include "xlsxwriter/hash_table.h"
|
||||
#include "xlsxwriter/hash_table.h"
|
||||
|
||||
STATIC int _worksheet_name_cmp(lxw_worksheet_name *name1,
|
||||
lxw_worksheet_name *name2);
|
||||
|
|
@ -2167,12 +2166,6 @@ workbook_add_chart(lxw_workbook *self, uint8_t type)
|
|||
{
|
||||
lxw_chart *chart;
|
||||
|
||||
if (type == LXW_CHART_NONE || type > LXW_CHART_RADAR_FILLED) {
|
||||
LXW_WARN_FORMAT1("workbook_add_chart(): invalid chart type: %d",
|
||||
type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a new chart object. */
|
||||
chart = lxw_chart_new(type);
|
||||
|
||||
|
|
@ -2660,10 +2653,6 @@ workbook_set_custom_property_datetime(lxw_workbook *self, const char *name,
|
|||
return LXW_ERROR_NULL_PARAMETER_IGNORED;
|
||||
}
|
||||
|
||||
if (lxw_datetime_validate(datetime) != LXW_NO_ERROR) {
|
||||
return LXW_ERROR_DATETIME_VALIDATION;
|
||||
}
|
||||
|
||||
/* Create a struct to hold the custom property. */
|
||||
custom_property = calloc(1, sizeof(struct lxw_custom_property));
|
||||
RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
|
||||
|
|
|
|||
|
|
@ -3007,15 +3007,13 @@ _worksheet_position_object_pixels(lxw_worksheet *self,
|
|||
height = height + y1;
|
||||
|
||||
/* Subtract the underlying cell widths to find the end cell. */
|
||||
while (width >= _worksheet_size_col(self, col_end, anchor)
|
||||
&& col_end < LXW_COL_MAX) {
|
||||
while (width >= _worksheet_size_col(self, col_end, anchor)) {
|
||||
width -= _worksheet_size_col(self, col_end, anchor);
|
||||
col_end++;
|
||||
}
|
||||
|
||||
/* Subtract the underlying cell heights to find the end cell. */
|
||||
while (height >= _worksheet_size_row(self, row_end, anchor)
|
||||
&& row_end < LXW_ROW_MAX) {
|
||||
while (height >= _worksheet_size_row(self, row_end, anchor)) {
|
||||
height -= _worksheet_size_row(self, row_end, anchor);
|
||||
row_end++;
|
||||
}
|
||||
|
|
@ -8334,9 +8332,9 @@ worksheet_write_datetime(lxw_worksheet *self,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = lxw_datetime_validate(datetime);
|
||||
if (err)
|
||||
return err;
|
||||
printf("worksheet_write_datetime(): %d-%02d-%02d - 1904: %d\n",
|
||||
datetime->year, datetime->month, datetime->day,
|
||||
self->use_1904_epoch);
|
||||
|
||||
excel_date =
|
||||
lxw_datetime_to_excel_date_with_epoch(datetime, self->use_1904_epoch);
|
||||
|
|
@ -9795,12 +9793,6 @@ worksheet_set_page_view(lxw_worksheet *self)
|
|||
void
|
||||
worksheet_set_paper(lxw_worksheet *self, uint8_t paper_size)
|
||||
{
|
||||
if (paper_size > 118) {
|
||||
LXW_WARN_FORMAT1("worksheet_set_paper(): invalid paper size: %d. "
|
||||
"Valid range is 0-118", paper_size);
|
||||
return;
|
||||
}
|
||||
|
||||
self->paper_size = paper_size;
|
||||
self->page_setup_changed = LXW_TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,18 @@ CTEST(chart, chart01) {
|
|||
char* got;
|
||||
char exp[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
"<c:chartSpace xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
"<c:chartSpace xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:c16r2=\"http://schemas.microsoft.com/office/drawing/2015/06/chart\">"
|
||||
"<c:date1904 val=\"0\"/>"
|
||||
"<c:lang val=\"en-US\"/>"
|
||||
"<c:roundedCorners val=\"0\"/>"
|
||||
"<mc:AlternateContent xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"
|
||||
"<mc:Choice xmlns:c14=\"http://schemas.microsoft.com/office/drawing/2007/8/2/chart\" Requires=\"c14\">"
|
||||
"<c14:style val=\"102\"/>"
|
||||
"</mc:Choice>"
|
||||
"<mc:Fallback>"
|
||||
"<c:style val=\"2\"/>"
|
||||
"</mc:Fallback>"
|
||||
"</mc:AlternateContent>"
|
||||
"<c:chart>"
|
||||
"<c:plotArea>"
|
||||
"<c:layout/>"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue