pub trait ExportFormat<R: GridRow>:
Send
+ Sync
+ 'static {
// Required methods
fn extension(&self) -> &str;
fn export(
&self,
table: &ExportTable<'_, R>,
cells: &CellExport<R>,
out: &mut dyn Write,
control: &ExportControl,
) -> Result<(), ExportError>;
}Expand description
Turns an export table into the bytes of a file or a stream: CSV, TSV, or an application format such as xlsx written with the application’s own library.
Called once per export, in the background (a TaskRunner job). It must
call ExportControl::advance as rows are written, at least once per
1024 rows, and stop with the error it returns: that is how progress shows
and how a cancelled export stops.
§Spreadsheets
The grid depends on no spreadsheet library. An application writes xlsx,
or any other format, with its own: in a format of its own, or in a
closure the grid hands the table to
(LiveGridState::export_with). The
table carries what such a file needs:
| The table tells | A spreadsheet makes of it |
|---|---|
ExportCell::value: Int, Float, Decimal, Bool, Text, Timestamp | A number, a boolean, a string or a date and time cell |
ExportCell::number_hint | The number format: the digits after the point, as on screen |
ExportColumn::title | The header row |
ExportColumn::bands, ExportTable::band_depth | Rows of merged header cells above the titles |
ExportColumn::width | The column width |
ExportColumn::align | The horizontal alignment |
ExportTable::has_header, ExportTable::frozen_columns, ExportRow::band | The frozen panes: the header rows, the leading columns and the top band |
ExportRow::depth, ExportRow::is_hidden, ExportRow::branch, GroupInfo::is_expanded | The outline level of a row, and rows hidden under a collapsed level |
ExportRow::line, ExportCell::is_aggregate | Summary rows set apart, or formulas in place of their values |
ExportCell::is_pending, ExportCell::row_value | An edit not yet confirmed: its value, or the stored one |
A spreadsheet keeps 15 significant digits: an Int beyond 2^53 loses its
last digits unless the format writes it as text.
The same walk over the table, without a library: a report with one line per row, indented by its depth, numbers with the digits the screen shows, captions and totals marked.
use std::io::Write;
use gpui_kit_grid::{
CellExport, CellValue, ExportControl, ExportError, ExportFormat, ExportLine, ExportTable,
GridRow,
};
struct OutlineReport;
impl<R: GridRow> ExportFormat<R> for OutlineReport {
fn extension(&self) -> &str {
"txt"
}
fn export(
&self,
table: &ExportTable<'_, R>,
_cells: &CellExport<R>,
out: &mut dyn Write,
control: &ExportControl,
) -> Result<(), ExportError> {
for (ix, row) in table.rows().iter().enumerate() {
let mark = match row.line() {
ExportLine::Caption => "▸ ",
ExportLine::Totals => "Σ ",
_ => "",
};
write!(out, "{:indent$}{mark}", "", indent = usize::from(row.depth()) * 2)?;
for column in table.columns() {
let Some(cell) = row.cell(column.column()) else {
continue;
};
let digits = cell
.number_hint()
.map_or(0, |hint| hint.fraction_digits() as usize);
match cell.value() {
CellValue::Float(value) => write!(out, "{value:.digits$} ")?,
CellValue::Int(value) => write!(out, "{value} ")?,
CellValue::Text(text) => write!(out, "{text} ")?,
_ => {}
}
}
writeln!(out)?;
if ix % 1024 == 1023 {
control.advance(1024)?;
}
}
control.advance(table.rows().len() % 1024)
}
}Required Methods§
Sourcefn export(
&self,
table: &ExportTable<'_, R>,
cells: &CellExport<R>,
out: &mut dyn Write,
control: &ExportControl,
) -> Result<(), ExportError>
fn export( &self, table: &ExportTable<'_, R>, cells: &CellExport<R>, out: &mut dyn Write, control: &ExportControl, ) -> Result<(), ExportError>
Writes table to out; text cells with cells, as a text format
does (a spreadsheet format reads ExportCell::value instead).