Skip to content

Commit

Permalink
worksheet: add initial embedded image support
Browse files Browse the repository at this point in the history
Feature request #417
  • Loading branch information
jmcnamara committed Jul 29, 2024
1 parent cf887d6 commit 4cfe3cc
Show file tree
Hide file tree
Showing 54 changed files with 2,229 additions and 26 deletions.
4 changes: 4 additions & 0 deletions .indent.pro
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
-T lxw_repeat_cols
-T lxw_repeat_rows
-T lxw_rich_string_tuple
-T lxw_rich_value
-T lxw_rich_value_rel
-T lxw_rich_value_structure
-T lxw_rich_value_types
-T lxw_row
-T lxw_row_col_options
-T lxw_row_t
Expand Down
37 changes: 37 additions & 0 deletions examples/embed_images.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* An example of embedding images into a worksheet using the libxlsxwriter
* library.
*
* Copyright 2014-2024, John McNamara, [email protected]
*
*/

#include "xlsxwriter.h"

int main() {

/* Create a new workbook and add a worksheet. */
lxw_workbook *workbook = workbook_new("embed_images.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);

/* Change some of the column widths for clarity. */
worksheet_set_column(worksheet, COLS("A:B"), 30, NULL);

/* Embed an image. */
worksheet_write_string(worksheet, CELL("A2"), "Embed an image in a cell:", NULL);
worksheet_embed_image(worksheet, CELL("B2"), "logo.png");

/* Make a row bigger and embed the image. */
worksheet_set_row(worksheet, 3, 72, NULL);
worksheet_write_string(worksheet, CELL("A4"), "Embed an image in a cell:", NULL);
worksheet_embed_image(worksheet, CELL("B4"), "logo.png");

/* Make a row bigger and embed the image. */
worksheet_set_row(worksheet, 5, 150, NULL);
worksheet_write_string(worksheet, CELL("A6"), "Embed an image in a cell:", NULL);
worksheet_embed_image(worksheet, CELL("B6"), "logo.png");

workbook_close(workbook);

return 0;
}
1 change: 1 addition & 0 deletions include/xlsxwriter/content_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void lxw_ct_add_shared_strings(lxw_content_types *content_types);
void lxw_ct_add_calc_chain(lxw_content_types *content_types);
void lxw_ct_add_custom_properties(lxw_content_types *content_types);
void lxw_ct_add_metadata(lxw_content_types *content_types);
void lxw_ct_add_rich_value(lxw_content_types *content_types);

/* Declarations required for unit testing. */
#ifdef TESTING
Expand Down
3 changes: 3 additions & 0 deletions include/xlsxwriter/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
typedef struct lxw_metadata {

FILE *file;
uint8_t has_dynamic_functions;
uint8_t has_embedded_images;
uint32_t num_embedded_images;

} lxw_metadata;

Expand Down
4 changes: 4 additions & 0 deletions include/xlsxwriter/packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
#include "vml.h"
#include "comment.h"
#include "metadata.h"
#include "rich_value.h"
#include "rich_value_rel.h"
#include "rich_value_types.h"
#include "rich_value_structure.h"

#define LXW_ZIP_BUFFER_SIZE (16384)

Expand Down
1 change: 1 addition & 0 deletions include/xlsxwriter/relationships.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ 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_rich_value_relationship(lxw_relationships *self);

/* Declarations required for unit testing. */
#ifdef TESTING
Expand Down
51 changes: 51 additions & 0 deletions include/xlsxwriter/rich_value.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* libxlsxwriter
*
* Copyright 2014-2024, John McNamara, [email protected]. See LICENSE.txt.
*
* rich_value - A libxlsxwriter library for creating Excel XLSX rich_value files.
*
*/
#ifndef __LXW_RICH_VALUE_H__
#define __LXW_RICH_VALUE_H__

#include <stdint.h>

#include "common.h"
#include "workbook.h"

/*
* Struct to represent a rich_value object.
*/
typedef struct lxw_rich_value {

FILE *file;
lxw_workbook *workbook;

} lxw_rich_value;


/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */

lxw_rich_value *lxw_rich_value_new(void);
void lxw_rich_value_free(lxw_rich_value *rich_value);
void lxw_rich_value_assemble_xml_file(lxw_rich_value *self);

/* Declarations required for unit testing. */
#ifdef TESTING

STATIC void _rich_value_xml_declaration(lxw_rich_value *self);

#endif /* TESTING */

/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */

#endif /* __LXW_RICH_VALUE_H__ */
50 changes: 50 additions & 0 deletions include/xlsxwriter/rich_value_rel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* libxlsxwriter
*
* Copyright 2014-2024, John McNamara, [email protected]. See LICENSE.txt.
*
* rich_value_rel - A libxlsxwriter library for creating Excel XLSX rich_value_rel files.
*
*/
#ifndef __LXW_RICH_VALUE_REL_H__
#define __LXW_RICH_VALUE_REL_H__

#include <stdint.h>

#include "common.h"

/*
* Struct to represent a rich_value_rel object.
*/
typedef struct lxw_rich_value_rel {

FILE *file;
uint32_t num_embedded_images;

} lxw_rich_value_rel;


/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */

lxw_rich_value_rel *lxw_rich_value_rel_new(void);
void lxw_rich_value_rel_free(lxw_rich_value_rel *rich_value_rel);
void lxw_rich_value_rel_assemble_xml_file(lxw_rich_value_rel *self);

/* Declarations required for unit testing. */
#ifdef TESTING

STATIC void _rich_value_rel_xml_declaration(lxw_rich_value_rel *self);

#endif /* TESTING */

/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */

#endif /* __LXW_RICH_VALUE_REL_H__ */
53 changes: 53 additions & 0 deletions include/xlsxwriter/rich_value_structure.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* libxlsxwriter
*
* Copyright 2014-2024, John McNamara, [email protected]. See LICENSE.txt.
*
* rich_value_structure - A libxlsxwriter library for creating Excel XLSX rich_value_structure files.
*
*/
#ifndef __LXW_RICH_VALUE_STRUCTURE_H__
#define __LXW_RICH_VALUE_STRUCTURE_H__

#include <stdint.h>

#include "common.h"

/*
* Struct to represent a rich_value_structure object.
*/
typedef struct lxw_rich_value_structure {

FILE *file;
uint8_t has_embedded_image_descriptions;

} lxw_rich_value_structure;


/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */

lxw_rich_value_structure *lxw_rich_value_structure_new(void);
void lxw_rich_value_structure_free(lxw_rich_value_structure
*rich_value_structure);
void lxw_rich_value_structure_assemble_xml_file(lxw_rich_value_structure
*self);

/* Declarations required for unit testing. */
#ifdef TESTING

STATIC void _rich_value_structure_xml_declaration(lxw_rich_value_structure
*self);

#endif /* TESTING */

/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */

#endif /* __LXW_RICH_VALUE_STRUCTURE_H__ */
49 changes: 49 additions & 0 deletions include/xlsxwriter/rich_value_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* libxlsxwriter
*
* Copyright 2014-2024, John McNamara, [email protected]. See LICENSE.txt.
*
* rich_value_types - A libxlsxwriter library for creating Excel XLSX rich_value_types files.
*
*/
#ifndef __LXW_RICH_VALUE_TYPES_H__
#define __LXW_RICH_VALUE_TYPES_H__

#include <stdint.h>

#include "common.h"

/*
* Struct to represent a rich_value_types object.
*/
typedef struct lxw_rich_value_types {

FILE *file;

} lxw_rich_value_types;


/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */

lxw_rich_value_types *lxw_rich_value_types_new(void);
void lxw_rich_value_types_free(lxw_rich_value_types *rich_value_types);
void lxw_rich_value_types_assemble_xml_file(lxw_rich_value_types *self);

/* Declarations required for unit testing. */
#ifdef TESTING

STATIC void _rich_value_types_xml_declaration(lxw_rich_value_types *self);

#endif /* TESTING */

/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */

#endif /* __LXW_RICH_VALUE_TYPES_H__ */
5 changes: 5 additions & 0 deletions include/xlsxwriter/workbook.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ typedef struct lxw_workbook {
struct lxw_worksheet_names *worksheet_names;
struct lxw_chartsheet_names *chartsheet_names;
struct lxw_image_md5s *image_md5s;
struct lxw_image_md5s *embedded_image_md5s;
struct lxw_image_md5s *header_image_md5s;
struct lxw_image_md5s *background_md5s;
struct lxw_charts *charts;
Expand Down Expand Up @@ -337,6 +338,10 @@ typedef struct lxw_workbook {
uint8_t has_vml;
uint8_t has_comments;
uint8_t has_metadata;
uint8_t has_embedded_images;
uint8_t has_dynamic_functions;

uint32_t num_embedded_images;

lxw_hash_table *used_xf_formats;
lxw_hash_table *used_dxf_formats;
Expand Down
37 changes: 36 additions & 1 deletion include/xlsxwriter/worksheet.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ enum cell_types {
DYNAMIC_ARRAY_FORMULA_CELL,
BLANK_CELL,
BOOLEAN_CELL,
ERROR_CELL,
COMMENT,
HYPERLINK_URL,
HYPERLINK_INTERNAL,
Expand Down Expand Up @@ -818,6 +819,7 @@ STAILQ_HEAD(lxw_selections, lxw_selection);
STAILQ_HEAD(lxw_data_validations, lxw_data_val_obj);
STAILQ_HEAD(lxw_cond_format_list, lxw_cond_format_obj);
STAILQ_HEAD(lxw_image_props, lxw_object_properties);
STAILQ_HEAD(lxw_embedded_image_props, lxw_object_properties);
STAILQ_HEAD(lxw_chart_props, lxw_object_properties);
STAILQ_HEAD(lxw_comment_objs, lxw_vml_obj);
STAILQ_HEAD(lxw_table_objs, lxw_table_obj);
Expand Down Expand Up @@ -2120,6 +2122,7 @@ typedef struct lxw_worksheet {
struct lxw_data_validations *data_validations;
struct lxw_cond_format_hash *conditional_formats;
struct lxw_image_props *image_props;
struct lxw_image_props *embedded_image_props;
struct lxw_chart_props *chart_data;
struct lxw_drawing_rel_ids *drawing_rel_ids;
struct lxw_vml_drawing_rel_ids *vml_drawing_rel_ids;
Expand Down Expand Up @@ -2193,7 +2196,7 @@ typedef struct lxw_worksheet {
uint8_t zoom_scale_normal;
uint8_t black_white;
uint8_t num_validations;
uint8_t has_dynamic_arrays;
uint8_t has_dynamic_functions;
char *vba_codename;
uint16_t num_buttons;

Expand Down Expand Up @@ -3783,6 +3786,34 @@ lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
size_t image_size,
lxw_image_options *options);

/**
* @brief TODO
*
* @param worksheet
* @param row
* @param col
* @param filename
* @return lxw_error
*/
lxw_error worksheet_embed_image(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
const char *filename);

/**
* @brief TODO
*
* @param worksheet
* @param row
* @param col
* @param filename
* @param options
* @return lxw_error
*/
lxw_error worksheet_embed_image_opt(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
const char *filename,
lxw_image_options *options);

/**
* @brief Set the background image for a worksheet.
*
Expand Down Expand Up @@ -5812,6 +5843,10 @@ void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);

void worksheet_set_error_cell(lxw_worksheet *worksheet,
lxw_object_properties *object_props,
uint32_t ref_id);

/* Declarations required for unit testing. */
#ifdef TESTING

Expand Down
Loading

0 comments on commit 4cfe3cc

Please sign in to comment.