Repository navigation
Expand file tree
/
Copy pathexcelreader.h
More file actions
505 lines (394 loc) · 19.4 KB
/
Copy pathexcelreader.h
File metadata and controls
505 lines (394 loc) · 19.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
#ifndef EXCELREADER_H
#define EXCELREADER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define XL_OK 0
#define XL_EOF -1
#define XL_BUFFER_TOO_SMALL -2
#define XL_INVALID_HANDLE -3
#define XL_INVALID_ARGUMENT -4
#define XL_ERROR -5
#define XL_STATUS_PASSWORD_REQUIRED (-6) /* the workbook is encrypted and no password was supplied */
#define XL_STATUS_PASSWORD_INCORRECT (-7) /* the supplied password did not match the workbook's verifier */
#define XL_ABI_VERSION 7
/* Threads: calls on one workbook handle may run on several threads at once. A row cursor, typed
reader, Arrow stream or writer handle is used by one thread at a time. A closed or unknown handle
returns XL_INVALID_HANDLE. xl_last_error reports the calling thread's last failure. */
#define XL_FORMAT_AUTO 0 /* sniffs XLS/XLSX/XLSB; does NOT detect CSV */
#define XL_FORMAT_XLS 1
#define XL_FORMAT_XLSX 2
#define XL_FORMAT_XLSB 3
#define XL_FORMAT_CSV 4 /* must be requested explicitly */
#define XL_CELL_EMPTY 0
#define XL_CELL_STRING 1
#define XL_CELL_NUMBER 2
#define XL_CELL_DATE 3
#define XL_CELL_BOOL 4
#define XL_CELL_FORMULA 5 /* no longer produced: a formula cell reports its cached result type */
#define XL_CELL_ERROR 6
#define XL_MAX_COLUMN_SPECS 16384
#define XL_MAX_COLUMN_NAME_BYTES 131068
typedef struct xl_workbook xl_workbook;
typedef struct xl_typed_reader xl_typed_reader;
typedef struct xl_rows xl_rows;
#define XL_SHEET_VISIBLE 0
#define XL_SHEET_HIDDEN 1
#define XL_SHEET_VERY_HIDDEN 2
typedef struct xl_row_cell {
int32_t column;
int32_t type;
int32_t value_len;
const uint8_t* value;
} xl_row_cell;
typedef struct xl_row {
int32_t cell_count;
xl_row_cell* cells;
} xl_row;
#define XL_OPT_DEFAULT 0
#define XL_OPT_FALSE 1
#define XL_OPT_TRUE 2
typedef struct xl_open_options {
int32_t struct_size;
int32_t csv_sniff_dialect;
int32_t csv_delimiter;
int32_t csv_quote;
int32_t csv_detect_bom;
int32_t csv_max_cell_bytes;
int32_t csv_intern_strings;
int64_t max_total_decompressed_bytes;
int32_t max_cell_bytes;
int64_t max_shared_string_bytes;
int32_t max_zip_entries;
int32_t prefetch_decompression;
int32_t intern_strings;
const uint8_t* password;
int32_t password_len;
int64_t source_cache_bytes;
int64_t max_buffered_bytes;
int32_t source_block_size;
/* XL_OPT_*: check each XLSX/XLSB ZIP entry against its CRC-32. On by default. */
int32_t verify_zip_checksums;
} xl_open_options;
int32_t xl_open_file(const uint8_t* path, int32_t path_len, int32_t format,
const xl_open_options* options, xl_workbook** out_handle);
int32_t xl_open_memory(const uint8_t* data, int32_t data_len, int32_t format,
const xl_open_options* options, xl_workbook** out_handle);
typedef struct xl_source {
int32_t struct_size;
void* user_data;
int64_t length;
int64_t (*read_at)(void* user_data, int64_t offset, uint8_t* buf, int64_t len);
void (*release)(void* user_data);
} xl_source;
int32_t xl_open_source(const xl_source* source, int32_t format,
const xl_open_options* options, xl_workbook** out_handle);
typedef struct xl_stream {
int32_t struct_size;
void* user_data;
int64_t (*read)(void* user_data, uint8_t* buf, int64_t len);
void (*release)(void* user_data);
} xl_stream;
int32_t xl_open_stream(const xl_stream* stream, int32_t format,
const xl_open_options* options, xl_workbook** out_handle);
void xl_set_source_error(const uint8_t* message, int32_t len);
int32_t xl_close(xl_workbook* handle);
int32_t xl_sheet_count(xl_workbook* handle, int32_t* out_count);
int32_t xl_sheet_name_at(xl_workbook* handle, int32_t index, uint8_t* buffer, int32_t capacity, int32_t* out_len);
int32_t xl_sheet_visibility_at(xl_workbook* handle, int32_t index, int32_t* out_visibility);
int32_t xl_sheet_index(xl_workbook* handle, const uint8_t* name, int32_t name_len, int32_t* out_index);
int32_t xl_is_date1904(xl_workbook* handle, int32_t* out_flag);
/* Excel tables. Passed as the `sheet` of any read call, XL_TABLE_SHEET(table) reads only the table's
range, header row first, with the column indexes of the sheet holding it. Rows and columns are
zero-based and include the header and totals rows. */
#define XL_TABLE_SHEET(table) (-2 - (table))
typedef struct xl_table_info {
int32_t sheet;
int32_t first_row;
int32_t last_row;
int32_t first_column;
int32_t last_column;
int32_t header_row_count;
int32_t totals_row_count;
} xl_table_info;
int32_t xl_table_count(xl_workbook* handle, int32_t* out_count);
int32_t xl_table_info_at(xl_workbook* handle, int32_t index, xl_table_info* out_info);
int32_t xl_table_name_at(xl_workbook* handle, int32_t index, uint8_t* buffer, int32_t capacity, int32_t* out_len);
/* Matches names ignoring case; *out_index is -1 when no table has the name. */
int32_t xl_table_index(xl_workbook* handle, const uint8_t* name, int32_t name_len, int32_t* out_index);
int32_t xl_rows_open(xl_workbook* handle, int32_t sheet, xl_rows** out_rows);
int32_t xl_rows_close(xl_rows* rows);
int32_t xl_rows_next(xl_rows* rows, uint8_t* buffer, int32_t capacity, int32_t* out_written);
int32_t xl_rows_next_view(xl_rows* rows, xl_row* out_row);
typedef struct xl_cell_view {
int32_t column;
int32_t type;
int32_t value_len;
int32_t has_number; /* number is valid; a cell carries text, a number, or both */
const uint8_t* value; /* valid only until the callback returns or the next call on the cursor, NOT NUL-terminated; NULL when value_len is 0 */
double number;
} xl_cell_view;
/* The next row as cell views owned by the cursor, valid until the next call on it or xl_rows_close.
Unlike xl_rows_next_view, numbers stay binary (has_number) instead of being formatted to text.
*out_cells may be NULL when *out_count is 0. */
int32_t xl_rows_next_cells(xl_rows* rows, const xl_cell_view** out_cells, int32_t* out_count);
/* cells may be NULL when cell_count is 0; a non-XL_OK return stops the walk and is returned verbatim (use positive codes); other xl_ calls are allowed from inside it */
typedef int32_t (*xl_row_fn)(const xl_cell_view* cells, int32_t cell_count, void* user_data);
int32_t xl_rows_foreach(xl_workbook* handle, int32_t sheet, xl_row_fn callback, void* user_data);
int32_t xl_rows_read_all_blob(xl_rows* rows, uint8_t* buffer, int32_t capacity, int32_t* out_written);
typedef struct xl_rows_decoded {
int32_t row_count;
xl_row* rows;
} xl_rows_decoded;
int32_t xl_rows_read_all_decoded(xl_rows* rows, xl_rows_decoded* out_rows);
void xl_free_rows(xl_rows_decoded* rows);
#define XL_T_STRING 0
#define XL_T_I64 1
#define XL_T_F64 2
#define XL_T_BOOL 3
#define XL_T_DATE 4 /* days since 1970-01-01, int32 */
#define XL_T_TIME 5 /* microseconds since midnight, int64 */
#define XL_T_TIMESTAMP 6 /* microseconds since 1970-01-01T00:00:00Z, int64 */
#define XL_T_STRING_DICT 7 /* xl_parse_arrow/xl_parse_arrow_stream only: utf8 dictionary, int32 indices */
typedef struct xl_column_spec {
const uint8_t* const* names;
const int32_t* name_lens;
int32_t name_count;
int32_t index;
int32_t type;
int32_t nullable;
} xl_column_spec;
typedef struct xl_column {
int32_t type;
int64_t length;
const void* values;
const uint8_t* validity;
const uint8_t* data;
int64_t data_len;
} xl_column;
typedef struct xl_table {
int32_t column_count;
int64_t row_count;
xl_column* columns;
} xl_table;
int32_t xl_parse_typed(xl_workbook* handle, int32_t sheet, const xl_column_spec* specs, int32_t spec_count,
int32_t header_row, int32_t degree_of_parallelism, xl_table* out_table);
void xl_free_table(xl_table* table);
int32_t xl_typed_reader_open(xl_workbook* handle, int32_t sheet, const xl_column_spec* specs, int32_t spec_count,
int32_t header_row, int64_t max_rows, xl_typed_reader** out_reader);
int32_t xl_typed_reader_next(xl_typed_reader* reader, xl_table* out_table);
void xl_typed_reader_close(xl_typed_reader* reader);
typedef struct xl_write_options {
int32_t struct_size;
int32_t sheet_name_len;
const uint8_t* sheet_name;
int32_t csv_delimiter;
int32_t csv_quote;
int32_t date1904;
int32_t use_shared_strings;
int32_t degree_of_parallelism;
int32_t batch_rows;
} xl_write_options;
/* Deprecated since 7.4, removed in 8.0: use xl_open_write_handle + xl_write_sheet, which also takes styles. */
int32_t xl_write_typed(const uint8_t* path, int32_t path_len,
int32_t format,
const xl_column_spec* specs,
const xl_table* table,
const xl_write_options* options);
typedef struct xl_buffer {
uint8_t* data;
int64_t len;
} xl_buffer;
/* Deprecated since 7.4, removed in 8.0: use xl_open_write_handle_to_memory + xl_write_sheet. */
int32_t xl_write_typed_to_memory(int32_t format,
const xl_column_spec* specs,
const xl_table* table,
const xl_write_options* options,
xl_buffer* out_buffer);
void xl_free_buffer(xl_buffer* buffer);
int32_t xl_encrypt_package(const uint8_t* package_path, int32_t package_path_len,
const uint8_t* destination_path, int32_t destination_path_len,
const uint8_t* password, int32_t password_len);
int32_t xl_encrypt_package_to_memory(const uint8_t* package, int32_t package_len,
const uint8_t* password, int32_t password_len,
xl_buffer* out_buffer);
typedef struct xl_inferred_schema {
xl_column_spec* columns;
int32_t column_count;
} xl_inferred_schema;
#define XL_INFER_PARSE_TEXT 1
int32_t xl_infer_schema(xl_workbook* handle, int32_t sheet, int32_t header_row, int32_t sample_size,
int32_t flags, xl_inferred_schema* out_schema);
void xl_free_schema(xl_inferred_schema* schema);
typedef struct xl_writer_handle xl_writer_handle;
int32_t xl_open_write_handle(const uint8_t* path, int32_t path_len, int32_t format,
const xl_write_options* options, xl_writer_handle** out_handle);
int32_t xl_open_write_handle_to_memory(int32_t format, const xl_write_options* options,
xl_writer_handle** out_handle);
int32_t xl_start_sheet(xl_writer_handle* handle, const uint8_t* name, int32_t name_len);
int32_t xl_start_row(xl_writer_handle* handle);
int32_t xl_write_string(xl_writer_handle* handle, const uint8_t* value, int32_t value_len);
int32_t xl_write_int64(xl_writer_handle* handle, int64_t value);
int32_t xl_write_float64(xl_writer_handle* handle, double value);
int32_t xl_write_bool(xl_writer_handle* handle, int32_t value);
int32_t xl_write_date(xl_writer_handle* handle, int32_t days_since_epoch);
int32_t xl_write_time(xl_writer_handle* handle, int64_t microseconds_since_midnight);
int32_t xl_write_timestamp(xl_writer_handle* handle, int64_t microseconds_since_epoch);
int32_t xl_write_null(xl_writer_handle* handle, int32_t type);
int32_t xl_end_row(xl_writer_handle* handle);
int32_t xl_end_sheet(xl_writer_handle* handle);
#define XL_FONT_BOLD 1
#define XL_FONT_ITALIC 2
#define XL_FONT_UNDERLINE 4
#define XL_FONT_STRIKETHROUGH 8
#define XL_BORDER_NONE 0
#define XL_BORDER_THIN 1
#define XL_BORDER_MEDIUM 2
#define XL_BORDER_DASHED 3
#define XL_BORDER_DOTTED 4
#define XL_BORDER_THICK 5
#define XL_BORDER_DOUBLE 6
#define XL_BORDER_HAIR 7
#define XL_BORDER_MEDIUM_DASHED 8
#define XL_BORDER_DASH_DOT 9
#define XL_BORDER_MEDIUM_DASH_DOT 10
#define XL_BORDER_DASH_DOT_DOT 11
#define XL_BORDER_MEDIUM_DASH_DOT_DOT 12
#define XL_BORDER_SLANT_DASH_DOT 13
#define XL_HALIGN_GENERAL 0
#define XL_HALIGN_LEFT 1
#define XL_HALIGN_CENTER 2
#define XL_HALIGN_RIGHT 3
#define XL_HALIGN_FILL 4
#define XL_HALIGN_JUSTIFY 5
#define XL_HALIGN_CENTER_CONTINUOUS 6
#define XL_HALIGN_DISTRIBUTED 7
#define XL_VALIGN_BOTTOM 0
#define XL_VALIGN_TOP 1
#define XL_VALIGN_CENTER 2
#define XL_VALIGN_JUSTIFY 3
#define XL_VALIGN_DISTRIBUTED 4
/* Colors are 0xRRGGBB, or -1 for unset: 0 is black, so a zeroed struct must set every unused color to -1. */
typedef struct xl_border {
int32_t style; /* XL_BORDER_*; XL_BORDER_NONE draws no edge */
int32_t color; /* -1: automatic */
} xl_border;
/* Strings are UTF-8 of the given length, not NUL-terminated; a NULL pointer or a length of 0 leaves them unset. */
typedef struct xl_cell_style {
int32_t struct_size;
int32_t number_format_len;
const uint8_t* number_format; /* NULL: General */
const uint8_t* font_name; /* NULL: the default font; 1-31 characters */
int32_t font_name_len;
int32_t font_flags; /* XL_FONT_* */
double font_size; /* points, 1-409; 0: the default size */
int32_t font_color;
int32_t fill_color; /* solid background */
int32_t horizontal_alignment; /* XL_HALIGN_* */
int32_t vertical_alignment; /* XL_VALIGN_* */
int32_t wrap_text; /* 0 or 1 */
int32_t indent; /* 0-15 */
int32_t rotation; /* degrees, -90 to 90, or 255 for stacked text */
xl_border left;
xl_border right;
xl_border top;
xl_border bottom;
} xl_cell_style;
/* Registers a style and returns its id; an equal style returns the same id. Id 0 is the general style
and needs no registering. An invalid value returns XL_INVALID_ARGUMENT and a format limit (fonts,
styles, XLS's 56 colors) XL_ERROR; neither affects the handle. CSV accepts every style call and
ignores it. */
int32_t xl_add_style(xl_writer_handle* handle, const xl_cell_style* style, int32_t* out_style_id);
/* Column style and width go after xl_start_sheet and before the sheet's first row. Nothing is
inherited on this path: a style without a number format on a column written with xl_write_time or
xl_write_timestamp shows the number, or the date alone. */
int32_t xl_set_column_style(xl_writer_handle* handle, int32_t column, int32_t style_id);
int32_t xl_set_column_width(xl_writer_handle* handle, int32_t column, double width); /* characters, 0-255 */
/* xl_start_row with a style for every cell of the row, beating column styles; height in points, at most
409, 0 for the default. */
int32_t xl_start_row_styled(xl_writer_handle* handle, int32_t style_id, double height);
/* Styles the next cell written, and only that one, over the row and column styles; xl_write_null then
writes a styled blank. xl_end_row with a style pending fails, ending the row. */
int32_t xl_style_next_cell(xl_writer_handle* handle, int32_t style_id);
#define XL_TABLE_NO_STYLE 1
#define XL_TABLE_NO_ROW_STRIPES 2
#define XL_TABLE_COLUMN_STRIPES 4
#define XL_TABLE_FIRST_COLUMN 8
#define XL_TABLE_LAST_COLUMN 16
/* struct_size is sizeof(xl_sheet_options), or 40 for the ABI 6 layout that ends at table_flags. The
style arrays have table->column_count entries; a NULL array sets none, a NULL entry or a width of 0
keeps that column's default. Column styles reach the data cells only, never the header row, and a
style without a number format keeps a DATE/TIME/TIMESTAMP column's format. An invalid style or width
returns XL_INVALID_ARGUMENT and a format limit XL_ERROR, both before the sheet is added, so neither
affects the handle. */
typedef struct xl_sheet_options {
int32_t struct_size;
int32_t table_name_len;
const uint8_t* table_name; /* NULL: a plain sheet; otherwise an Excel table (XLSX/XLSB only) */
int32_t table_style_len;
const uint8_t* table_style; /* NULL: TableStyleMedium2 */
int32_t table_flags; /* XL_TABLE_* */
const xl_cell_style* const* column_styles;
const double* column_widths; /* characters, 0-255 */
const xl_cell_style* header_style;
} xl_sheet_options;
/* One whole sheet, as xl_write_typed writes it; fails while a sheet is open. A NULL options writes a
plain sheet; a table needs every column named. */
int32_t xl_write_sheet(xl_writer_handle* handle, const uint8_t* name, int32_t name_len,
const xl_column_spec* specs, const xl_table* table, const xl_sheet_options* options);
/* A path handle writes beside its path and replaces the file only when this returns XL_OK; on failure
any existing file is left as it was. After a failed xl_write_sheet the handle has no output: this and
xl_write_handle_bytes return XL_ERROR. */
int32_t xl_close_write_handle(xl_writer_handle* handle);
int32_t xl_write_handle_bytes(xl_writer_handle* handle, xl_buffer* out_buffer);
/* Discards everything written and releases the handle; an existing file at the path is left as it was. */
int32_t xl_abort_write_handle(xl_writer_handle* handle);
typedef int32_t (*xl_csv_seed_fn) (void** out_state, void* user_data);
typedef int32_t (*xl_csv_accumulate_fn)(void* state, const xl_row* row, void* user_data);
typedef int32_t (*xl_csv_combine_fn) (void* acc, void* next, void* user_data);
typedef void (*xl_csv_free_state_fn)(void* state, void* user_data);
typedef struct xl_csv_aggregation {
int32_t struct_size;
xl_csv_seed_fn seed;
xl_csv_accumulate_fn accumulate;
xl_csv_combine_fn combine;
xl_csv_free_state_fn free_state;
void* user_data;
} xl_csv_aggregation;
typedef struct xl_csv_parallel_options {
int32_t struct_size;
int32_t degree_of_parallelism;
int32_t header_row;
int32_t delimiter;
int32_t quote;
int32_t detect_bom;
int32_t max_cell_bytes;
} xl_csv_parallel_options;
int32_t xl_csv_aggregate_file(const uint8_t* path, int32_t path_len,
const xl_csv_aggregation* agg,
const xl_csv_parallel_options* options,
void** out_state);
int32_t xl_csv_aggregate_memory(const uint8_t* data, int32_t data_len,
const xl_csv_aggregation* agg,
const xl_csv_parallel_options* options,
void** out_state);
typedef int32_t (*xl_accumulate_fn)(void* state, const xl_cell_view* cells, int32_t cell_count, void* user_data);
typedef struct xl_aggregation {
int32_t struct_size;
xl_csv_seed_fn seed;
xl_accumulate_fn accumulate;
xl_csv_combine_fn combine;
xl_csv_free_state_fn free_state;
void* user_data;
} xl_aggregation;
/* seeds once per chunk; combine(acc, next) runs in source order and must not free next; free_state runs on the calling thread after the run */
int32_t xl_aggregate(xl_workbook* handle, int32_t sheet, const xl_aggregation* agg,
int32_t header_row, int32_t degree_of_parallelism, void** out_state);
int32_t xl_last_error(uint8_t* buffer, int32_t capacity, int32_t* out_len);
const uint8_t* xl_last_error_ptr(int32_t* out_len);
int32_t xl_abi_version(void);
#ifdef __cplusplus
}
#endif
#endif /* EXCELREADER_H */