/* * write_sheet: * * @output: the stream * @sheet: the gnumeric sheet * * set up a table and call write_row for each row */ static void write_sheet (GsfOutput *output, Sheet *sheet, html_version_t version, GOFileSaveScope save_scope) { GnmRange total_range; gint row; switch (version) { case HTML40: case HTML40F: case XHTML: gsf_output_puts (output, "<p></p><table cellspacing=\"0\" cellpadding=\"3\">\n"); break; default: gsf_output_puts (output, "<p><table border=\"1\">\n"); break; } if (save_scope != GO_FILE_SAVE_RANGE) { gsf_output_puts (output, "<caption>"); html_print_encoded (output, sheet->name_unquoted); gsf_output_puts (output, "</caption>\n"); } total_range = sheet_get_extent (sheet, TRUE, TRUE); for (row = total_range.start.row; row <= total_range.end.row; row++) { gsf_output_puts (output, "<tr>\n"); write_row (output, sheet, row, &total_range, version); gsf_output_puts (output, "</tr>\n"); } gsf_output_puts (output, "</table>\n"); }
int gnumeric_sheet_get_size(GnumericSheetPtr sheet, int *w, int *h) { Sheet *s = (Sheet *)sheet; //GnmSheetSize const *size = gnm_sheet_get_size(sheet); GnmRange range = sheet_get_extent(s,FALSE); if (w!=NULL) *w = range.end.col+1; if (h!=NULL) *h = range.end.row+1; }
static GOFileSaver * find_file_saver(const gchar *filename, WorkbookView *view, Workbook *workbook, GODoc *document, GError **error) { GOFileSaver *saver = NULL; const gchar saver_id[] = "Gnumeric_stf:stf_assistant"; GString *saver_options; gint i, n_sheets; GError *local_error = NULL; saver = go_file_saver_for_id(saver_id); if (!saver) { g_set_error(error, CHUPA_DECOMPOSER_ERROR, CHUPA_DECOMPOSER_ERROR_FEED, "[decomposer][excel][feed][error][saver][create][%s]" ": file saver doesn't found: <%s>", filename, saver_id); return NULL; } saver_options = g_string_new("eol=unix separator='\t'"); n_sheets = workbook_sheet_count(workbook); for (i = 0; i < n_sheets; i++) { Sheet *sheet; GnmRange total_range; sheet = workbook_sheet_by_index(workbook, i); total_range = sheet_get_extent(sheet, TRUE); if (sheet_is_region_empty(sheet, &total_range)) { chupa_debug("[decomposer][excel][feed][saver][sheet][ignore][%s]" ": ignore empty sheet: <%s>(%d)", filename, sheet->name_quoted, i); continue; } g_string_append_printf(saver_options, " sheet=%s", sheet->name_quoted); chupa_debug("[decomposer][excel][feed][saver][sheet][use][%s]: <%s>(%d)", filename, sheet->name_quoted, i); } if (go_file_saver_set_export_options(saver, document, saver_options->str, &local_error)) { g_set_error(error, CHUPA_DECOMPOSER_ERROR, CHUPA_DECOMPOSER_ERROR_FEED, "[decomposer][excel][feed][error][saver][option][%s]" ": <%s>(%s): <%s>(%s:%d)", filename, saver_id, saver_options->str, local_error->message, g_quark_to_string(local_error->domain), local_error->code); g_error_free(local_error); saver = NULL; } g_string_free(saver_options, TRUE); return saver; }
/* * write_sheet: * * @output: the stream * @sheet: the gnumeric sheet * * set up a table and call write_row for each row */ static void write_sheet (GsfOutput *output, Sheet *sheet, GOFileSaveScope save_scope) { GnmRange total_range; gint row; total_range = sheet_get_extent (sheet, FALSE, TRUE); for (row = total_range.start.row; row <= total_range.end.row; row++) { write_row (output, sheet, row, &total_range); } gsf_output_puts (output, "---\n"); }
static void sylk_write_sheet (SylkWriter *state) { GnmRange extent; /* collect style and font info */ extent = sheet_get_extent (state->sheet, FALSE, TRUE); sheet_style_foreach (state->sheet, (GFunc)cb_sylk_collect_styles, state); sheet_cell_foreach (state->sheet, (GHFunc)cb_sylk_collect_cell_styles, state); /* * 1) formats P;P..... * 2.1) ?? fonts P;F.... * 2.2) indexed fonts P;E.... * 3) global formats F; */ /* Global Formatting */ /* F;P0;DG0G10;SM0;Z;M280;N3 10 */ /* Bounds */ gsf_output_printf (state->output, "B;Y%d;X%d;D0 0 %d %d\r\n", extent.end.row + 1, extent.end.col + 1, extent.end.row, extent.end.col); /* Global options */ gsf_output_printf (state->output, "O;%c%d %f", (state->wb->iteration.enabled ? 'A' : 'G'), state->wb->iteration.max_number, state->wb->iteration.tolerance); if (!state->sheet->convs->r1c1_addresses) gsf_output_puts (state->output, ";L"); if (!state->wb->recalc_auto) gsf_output_puts (state->output, ";M"); gsf_output_printf (state->output, ";V%d", workbook_date_conv (state->wb)->use_1904 ? 4 : 0); if (state->sheet->hide_zero) gsf_output_puts (state->output, ";Z"); gsf_output_write (state->output, 2, "\r\n"); /* dump content */ state->cur_row = -1; sheet_foreach_cell_in_range (state->sheet, CELL_ITER_IGNORE_BLANK, extent.start.col, extent.start.row, extent.end.col, extent.end.row, (CellIterFunc) cb_sylk_write_cell, state); }
/** * range_clip_to_finite : * @range : * @sheet : the sheet in which @range lives * * Clip the range to the area of the sheet with content. * if the range reaches the edge * * The idea here is that users may select a whole column or ow when they * really are only concerned with the extent of the sheet. * On the otehr hand, if users select any smaller region they probably * intend to selec tjust that. * * WARNING THIS IS EXPENSIVE! **/ void range_clip_to_finite (GnmRange *range, Sheet *sheet) { GnmRange extent; /* FIXME : This seems expensive. We should see if there is a faster * way of doing this. possibly using a flag for content changes, and * using the current values as a cache */ extent = sheet_get_extent (sheet, FALSE); if (range->end.col >= gnm_sheet_get_max_cols (sheet) - 1) range->end.col = extent.end.col; if (range->end.row >= gnm_sheet_get_max_rows (sheet) - 1) range->end.row = extent.end.row; }
/** * stf_export_sheet: * @stfe: an export options struct * @sheet: the sheet to export * * Writes the @sheet to the callback function * * Return value: returns TRUE on success, FALSE otherwise **/ static gboolean stf_export_sheet (GnmStfExport *stfe, Sheet *sheet) { int col, row; GnmRange r; GnmRangeRef *range; g_return_val_if_fail (stfe != NULL, FALSE); g_return_val_if_fail (IS_SHEET (sheet), FALSE); range = g_object_get_data (G_OBJECT (sheet->workbook), "ssconvert-range"); if (range) { Sheet *start_sheet, *end_sheet; GnmEvalPos ep; gnm_rangeref_normalize (range, eval_pos_init_sheet (&ep, sheet), &start_sheet, &end_sheet, &r); if (start_sheet != sheet) return TRUE; } else r = sheet_get_extent (sheet, FALSE, TRUE); for (row = r.start.row; row <= r.end.row; row++) { for (col = r.start.col; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, row); if (!stf_export_cell (stfe, cell)) return FALSE; } if (!gsf_output_csv_write_eol (GSF_OUTPUT_CSV (stfe))) return FALSE; } return TRUE; }
G_MODULE_EXPORT void paradox_file_save (GOFileSaver const *fs, GOIOContext *io_context, WorkbookView const *wb_view, GsfOutput *output) { Sheet *sheet; GnmRange r; gint row, col, i; pxdoc_t *pxdoc = NULL; pxfield_t *pxf; char *data; char *tmpfilename; sheet = wb_view_cur_sheet (wb_view); if (sheet == NULL) { go_io_error_string (io_context, _("Cannot get default sheet.")); return; } r = sheet_get_extent (sheet, FALSE, TRUE); #ifdef PX_MEMORY_DEBUGGING pxdoc = PX_new2 (gn_errorhandler, PX_mp_malloc, PX_mp_realloc, PX_mp_free); #else pxdoc = PX_new2 (gn_errorhandler, gn_malloc, gn_realloc, gn_free); #endif /* Read the field specification and build the field array for * PX_create_fp(). The memory is freed by PX_delete() including * the memory for the field name. */ if ((pxf = (pxfield_t *) pxdoc->malloc (pxdoc, (r.end.col+1)*sizeof (pxfield_t), _("Allocate memory for field definitions."))) == NULL){ go_io_error_string (io_context, _("Cannot allocate memory for field definitions.")); PX_delete (pxdoc); return; } for (col = r.start.col; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, 0); if (gnm_cell_is_empty (cell)) { go_io_error_string (io_context, _("First line of sheet must contain database specification.")); PX_delete (pxdoc); return; } else { gchar *fieldstr, *tmp; int len, needsize, needprecision; i = col; fieldstr = gnm_cell_get_rendered_text (cell); needsize = 0; needprecision = 0; /* Search for the first comma which is the end of the field name. */ tmp = strchr (fieldstr, ','); if (NULL == tmp) { g_warning (_("Field specification must be a comma separated value (Name,Type,Size,Prec).")); PX_delete (pxdoc); return; } len = tmp-fieldstr; if (NULL == (pxf[i].px_fname = pxdoc->malloc (pxdoc, len+1, _("Allocate memory for column name.")))) { g_warning (_("Could not allocate memory for %d. field name."), i); PX_delete (pxdoc); return; } strncpy (pxf[i].px_fname, fieldstr, len); pxf[i].px_fname[len] = '\0'; /* Get the field Type */ fieldstr = tmp+1; if (*fieldstr == '\0') { g_warning (_("%d. field specification ended unexpectedly."), i); PX_delete (pxdoc); return; } if (*fieldstr == ',') { g_warning (_("%d. field specification misses type."), i); PX_delete (pxdoc); return; } switch ((int) *fieldstr) { case 'S': pxf[i].px_ftype = pxfShort; pxf[i].px_flen = 2; break; case 'I': pxf[i].px_ftype = pxfLong; pxf[i].px_flen = 4; break; case 'A': case 'C': pxf[i].px_ftype = pxfAlpha; needsize = 1; break; case 'N': pxf[i].px_ftype = pxfNumber; pxf[i].px_flen = 8; break; case '$': pxf[i].px_ftype = pxfCurrency; pxf[i].px_flen = 8; break; case 'L': pxf[i].px_ftype = pxfLogical; pxf[i].px_flen = 1; break; case 'D': pxf[i].px_ftype = pxfDate; pxf[i].px_flen = 4; break; case '+': pxf[i].px_ftype = pxfAutoInc; pxf[i].px_flen = 4; break; case '@': pxf[i].px_ftype = pxfTimestamp; pxf[i].px_flen = 8; break; case 'T': pxf[i].px_ftype = pxfTime; pxf[i].px_flen = 4; break; case '#': pxf[i].px_ftype = pxfBCD; pxf[i].px_flen = 17; needprecision = 1; break; case 'M': pxf[i].px_ftype = pxfMemoBLOb; needsize = 1; break; case 'B': pxf[i].px_ftype = pxfBLOb; needsize = 1; break; case 'F': pxf[i].px_ftype = pxfFmtMemoBLOb; needsize = 1; break; case 'Y': pxf[i].px_ftype = pxfBytes; needsize = 1; break; default: g_warning (_("%d. field type '%c' is unknown."), i, *fieldstr); pxdoc->free (pxdoc, pxf); PX_delete (pxdoc); return; } if (needsize || needprecision) { char *endptr; /* find end of type definition */ tmp = strchr (fieldstr, ','); if (NULL == tmp || *(tmp+1) == '\0') { g_warning (_("Field specification misses the column size.")); PX_delete (pxdoc); return; } fieldstr = tmp+1; if (needsize) pxf[i].px_flen = strtol (fieldstr, &endptr, 10); else pxf[i].px_fdc = strtol (fieldstr, &endptr, 10); if ((endptr == NULL) || (fieldstr == endptr)) { g_warning (_("Field specification misses the column size.")); PX_delete (pxdoc); return; } if (*endptr != '\0') { /* There is also precision which we do not care about. */ fieldstr = endptr+1; g_warning (_("The remainder '%s' of the specification for field %d is being disregarded."), fieldstr, i+1); } } } } /* Create the paradox file */ tmpfilename = tempnam ("/tmp", NULL); if (0 > PX_create_file (pxdoc, pxf, r.end.col+1, tmpfilename, pxfFileTypNonIndexDB)) { g_warning (_("Could not create output file.")); PX_delete (pxdoc); return; } PX_set_inputencoding (pxdoc, "UTF-8"); PX_set_parameter (pxdoc, "targetencoding", "CP1252"); PX_set_tablename (pxdoc, sheet->name_unquoted); if ((data = (char *) pxdoc->malloc (pxdoc, pxdoc->px_head->px_recordsize, _("Allocate memory for record data."))) == NULL) { g_warning (_("Could not allocate memory for record data.")); PX_close (pxdoc); PX_delete (pxdoc); return; } /* Process all cells */ for (row = r.start.row+1; row <= r.end.row; row++) { int i; int offset; offset = 0; memset (data, 0, pxdoc->px_head->px_recordsize); for (col = r.start.col, i = 0; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, row); if (!gnm_cell_is_empty (cell)) { char *fieldstr = gnm_cell_get_rendered_text (cell); switch (pxf[i].px_ftype) { case pxfShort: { int value = value_get_as_int (cell->value); PX_put_data_short (pxdoc, &data[offset], 2, (short int) value); break; } case pxfLong: case pxfAutoInc: { int value = value_get_as_int (cell->value); PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfTimestamp: { double value = value_get_as_float (cell->value); /* 60 would be 29.2.1900 which didn't exist. */ if (value < 60) value += 1.0; value += 693594; value *= 86400000.0; PX_put_data_double (pxdoc, &data[offset], 8, value); break; } case pxfCurrency: case pxfNumber: { double value = value_get_as_float (cell->value); PX_put_data_double(pxdoc, &data[offset], 8, value); break; } case pxfAlpha: { char *value = fieldstr; int nlen = strlen (value); if (nlen > pxf[i].px_flen) /* xgettext : last %d gives the number of characters.*/ /* This is input to ngettext. */ g_warning (ngettext ("Field %d in line %d has possibly " "been cut off. Data has %d character.", "Field %d in line %d has possibly " "been cut off. Data has %d characters.", nlen), i+1, row+1, nlen); PX_put_data_alpha (pxdoc, &data[offset], pxf[i].px_flen, value); break; } case pxfMemoBLOb: case pxfFmtMemoBLOb: { char *value = fieldstr; if (0 > PX_put_data_blob (pxdoc, &data[offset], pxf[i].px_flen, value, strlen (value))) { g_warning (_("Field %d in row %d could not be written."), i+1, row+1); } break; } case pxfDate: { long value = value_get_as_int (cell->value); /* 60 would be 29.2.1900 which didn't exist. */ if (value < 60) value++; value += 693594; PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfTime: { double dtmp; int value; dtmp = value_get_as_float (cell->value); dtmp -= ((int) dtmp); value = (int) (dtmp * 86400000.0); PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfLogical: { gboolean err; /* Ignored */ gboolean value = value_get_as_bool (cell->value, &err); PX_put_data_byte (pxdoc, &data[offset], 1, value ? 1 : 0); break; } case pxfBCD: PX_put_data_bcd (pxdoc, &data[offset], pxf[i].px_fdc, fieldstr); break; } } offset += pxf[i].px_flen; i++; } if ((i > 0) && (0 > PX_put_record (pxdoc, data))) { g_warning (_("Could not write record number %d."), i+1); pxdoc->free (pxdoc, data); PX_close (pxdoc); PX_delete (pxdoc); return; } } pxdoc->free (pxdoc, data); PX_close (pxdoc); PX_delete (pxdoc); #ifdef PX_MEMORY_DEBUGGING PX_mp_list_unfreed (); #endif { FILE *fp; size_t size; fp = fopen (tmpfilename, "r"); if (fp) { data = g_malloc (8192); while (0 != (size = fread (data, 1, 8192, fp))) gsf_output_write (output, size, data); fclose (fp); g_free (data); } else g_warning ("Cannot open %s\n", tmpfilename); unlink (tmpfilename); } }
/* * Write _current_ sheet of the workbook to a DIF format file */ void dif_file_save (GOFileSaver const *fs, GOIOContext *io_context, WorkbookView const *wbv, GsfOutput *out) { GnmLocale *locale; Sheet *sheet; GnmRange r; gint row, col; gboolean ok = TRUE; sheet = wb_view_cur_sheet (wbv); if (sheet == NULL) { go_io_error_string (io_context, _("Cannot get default sheet.")); return; } r = sheet_get_extent (sheet, FALSE, TRUE); /* Write out the standard headers */ gsf_output_puts (out, "TABLE\n" "0,1\n" "\"GNUMERIC\"\n"); gsf_output_printf (out, "VECTORS\n" "0,%d\n" "\"\"\n", r.end.col+1); gsf_output_printf (out, "TUPLES\n" "0,%d\n" "\"\"\n", r.end.row+1); gsf_output_puts (out, "DATA\n" "0,0\n" "\"\"\n"); locale = gnm_push_C_locale (); /* Process all cells */ for (row = r.start.row; ok && row <= r.end.row; row++) { gsf_output_puts (out, "-1,0\n" "BOT\n"); for (col = r.start.col; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, row); if (gnm_cell_is_empty (cell)) { gsf_output_puts(out, "1,0\n" "\"\"\n"); } else if (VALUE_IS_BOOLEAN (cell->value)) { if (value_get_as_checked_bool (cell->value)) gsf_output_puts(out, "0,1\n" "TRUE\n"); else gsf_output_puts(out, "0,0\n" "FALSE\n"); } else if (VALUE_IS_ERROR (cell->value)) { if (value_error_classify (cell->value) == GNM_ERROR_NA) gsf_output_puts(out, "0,0\n" "NA\n"); else gsf_output_puts(out, "0,0\n" "ERROR\n"); } else if (VALUE_IS_FLOAT (cell->value)) gsf_output_printf (out, "0,%" GNM_FORMAT_g "\n" "V\n", value_get_as_float (cell->value)); else { gchar *str = gnm_cell_get_rendered_text (cell); ok = gsf_output_printf (out, "1,0\n" "\"%s\"\n", str); g_free (str); } } } gsf_output_puts (out, "-1,0\n" "EOD\n"); gnm_pop_C_locale (locale); if (!ok) go_io_error_string (io_context, _("Error while saving DIF file.")); }
/* * write every sheet of the workbook to a roff file * * FIXME: Should roff quote sheet name (and everything else) */ void roff_file_save (GOFileSaver const *fs, GOIOContext *io_context, WorkbookView const *wb_view, GsfOutput *output) { GSList *sheets, *ptr; GnmCell *cell; int row, col, fontsize, v_size; Workbook *wb = wb_view_get_workbook (wb_view); g_return_if_fail (wb != NULL); gsf_output_printf (output, ".\\\" TROFF file\n"); gsf_output_printf (output, ".fo ''%%''\n"); sheets = workbook_sheets (wb); for (ptr = sheets ; ptr != NULL ; ptr = ptr->next) { Sheet *sheet = ptr->data; GnmRange r = sheet_get_extent (sheet, FALSE, TRUE); gsf_output_printf (output, "%s\n\n", sheet->name_unquoted); gsf_output_printf (output, ".TS H\n"); gsf_output_printf (output, "allbox;\n"); for (row = r.start.row; row <= r.end.row; row++) { ColRowInfo const * ri; ri = sheet_row_get_info (sheet, row); if (ri->needs_respan) row_calc_spans ((ColRowInfo *) ri, row, sheet); if (row > r.start.row) gsf_output_printf (output, ".T&\n"); /* define alignments, bold etc. per cell */ v_size = DEFSIZE; for (col = r.start.col; col <= r.end.col; col++) { cell = sheet_cell_get (sheet, col, row); if (col > r.start.col) gsf_output_printf (output, " "); if (!cell) { gsf_output_printf (output, "l"); } else { GnmStyle const *style = gnm_cell_get_style (cell); if (!style) break; if (gnm_style_get_align_h (style) & GNM_HALIGN_RIGHT) gsf_output_printf (output, "r"); else if (gnm_style_get_align_h (style) == GNM_HALIGN_CENTER || /* FIXME : center across selection is different */ gnm_style_get_align_h (style) == GNM_HALIGN_CENTER_ACROSS_SELECTION || gnm_style_get_align_h (style) == GNM_HALIGN_DISTRIBUTED) gsf_output_printf (output, "c"); else gsf_output_printf (output, "l"); if (font_is_monospaced (style)) { if (gnm_style_get_font_bold (style) && gnm_style_get_font_italic (style)) gsf_output_printf (output, "fCBI"); else if (gnm_style_get_font_bold (style)) gsf_output_printf (output, "fCB"); else if (gnm_style_get_font_italic (style)) gsf_output_printf (output, "fCI"); else gsf_output_printf (output, "fCR"); } else if (font_is_helvetica (style)) { if (gnm_style_get_font_bold (style) && gnm_style_get_font_italic (style)) gsf_output_printf (output, "fHBI"); else if (gnm_style_get_font_bold (style)) gsf_output_printf (output, "fHB"); else if (gnm_style_get_font_italic (style)) gsf_output_printf (output, "fHI"); else gsf_output_printf (output, "fHR"); } else { /* default is times */ if (gnm_style_get_font_bold (style) && gnm_style_get_font_italic (style)) gsf_output_printf (output, "fTBI"); else if (gnm_style_get_font_bold (style)) gsf_output_printf (output, "fTB"); else if (gnm_style_get_font_italic (style)) gsf_output_printf (output, "fTI"); } fontsize = gnm_style_get_font_size (style); if (fontsize) { gsf_output_printf (output, "p%d", fontsize); v_size = v_size > fontsize ? v_size : fontsize; } } } gsf_output_printf (output, ".\n"); gsf_output_printf (output, ".vs %.2fp\n", 2.5 + v_size); for (col = r.start.col; col <= r.end.col; col++) { if (col > r.start.col) gsf_output_printf (output, "\t"); cell = sheet_cell_get (sheet, col, row); if (!cell) { /* empty cell */ gsf_output_printf (output, " "); } else { roff_fprintf (output, cell); } } gsf_output_printf (output, "\n"); if (row == r.start.row) gsf_output_printf (output, ".TH\n"); } gsf_output_printf (output, ".TE\n\n"); } g_slist_free (sheets); }