Giter VIP home page Giter VIP logo

simple_excel_writer's Introduction

simple_excel_writer

simple excel writer in Rust

Build Status Documentation

Example

#[macro_use]
extern crate simple_excel_writer as excel;

use excel::*;

fn main() {
    let mut wb = Workbook::create("/tmp/b.xlsx");
    let mut sheet = wb.create_sheet("SheetName");

    // set column width
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 80.0 });
    sheet.add_column(Column { width: 60.0 });

    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","XML Remark"])?;
        sw.append_row(row!["Amy", (), true,"<xml><tag>\"Hello\" & 'World'</tag></xml>"])?;
        sw.append_blank_rows(2);
        sw.append_row(row!["Tony", blank!(2), "retired"])
    }).expect("write excel error!");

    let mut sheet = wb.create_sheet("Sheet2");
    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","Remark"])?;
        sw.append_row(row!["Amy", "Manager", true])
    }).expect("write excel error!");

    let euro_fmt_idx = wb.add_cust_number_format("\"\"#,##0.00".to_string());
    let weight_fmt_idx = wb.add_cust_number_format("#,##0.0\" KG\"".to_string());
    let mut sheet_num_fmt = wb.create_sheet("SheetNumFormatted");
    sheet_num_fmt.add_column(Column { width: 30.0 });
    sheet_num_fmt.add_column(Column { width: 30.0 });
    wb.write_sheet(&mut sheet_num_fmt, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Weight", "Price"])?;
        sw.append_row(row![(700.5, weight_fmt_idx), (12045.99, euro_fmt_idx)])?;
        sw.append_row(row![(1525.0, weight_fmt_idx), (25999.00, euro_fmt_idx)])
    }).expect("write excel error!");

    wb.close().expect("close excel error!");
}

Todo

  • support style

Change Log

0.2.0 (2022-03-11)

  • support WASM !

0.1.9 (2021-10-28)

  • support formula
  • support NaiveDate & NaiveDateTime
  • format dates and date times
  • Sheet name validation
  • remove unndecessary bzip2 dependency

many thanks to all contributors !

0.1.7 (2020-04-29)

  • support create-in-memory mode, thanks to Maxburke.
This change creates all worksheet files in-memory and only writes them
to disk once the XLSX file is closed.

A new option for creating a version that is in-memory only is available
with `Worksheet::create_in_memory()` which returns the buffer holding
the completed XLSX file contents when closed.

0.1.6 (2020-04-06)

  • support shared strings between worksheets, thanks to Mikael Edlund.

0.1.5 (2019-03-21)

  • support Windows platform, thanks to Carl Fredrik Samson.

0.1.4 (2017-03-24)

  • escape xml characters.

0.1.3 (2017-01-03)

  • support 26+ columns .
  • fix column width bug.

0.1.2 (2017-01-02)

  • support multiple sheets

0.1 (2017-01-01)

  • generate the basic xlsx file

License

Apache-2.0

simple_excel_writer's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

simple_excel_writer's Issues

Compatibility with Webassembly

Hello,

I am hoping to use this library to serialize excel files in the browser. Currently it is not possible to do so because of line 153 here,
Screen Shot 2022-03-04 at 6 09 10 PM

Clicking through we find a call to time::now, which is not available to webassembly when executed in the browser
Screen Shot 2022-03-04 at 6 09 44 PM

the easiest solutions that i see are to either remove the "time" feature from zip or to not call FileOptions::default(), but rather give an explicit time that does not result in a call to the standard library.
Screen Shot 2022-03-04 at 7 07 47 PM

I am happy to open a pr for either of these solutions if they make sense for this library.

First test running of example

image
I'm glad to see .xlsx file saved successfully with the above screenshot.
However, it seems that the code "< x m l>< t a g >" doesn't works.

Configuring compression method

Now it uses zip::CompressionMethod::Stored by default and resulting files are very large. It would be great if I could somehow choose another compression method. Thank you!

impl `std::fmt::Display` for `CellValue`

It's happened on a few occasions that I've needed to reference the value of a cell.
Would implementing std::fmt::Display for CellValue be a good idea?

A quick example of a time I've had to do this is when writing a program to format report outputs, one of which required the name of each sheet to be named after the value of a column value (eg. format!("PO Line {}", line_no); )

This solution to the issue was provided to me, in the form of a function, by a user on Reddit:

fn display_cellvalue(cellvalue: &CellValue) -> impl fmt::Display + '_ {
    struct Wrapper<'a>(&'a CellValue);
    impl<'a> fmt::Display for Wrapper<'a> {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match &self.0 {
                CellValue::Bool(b) => write!(f, "{}", b),
                CellValue::Number(n) => write!(f, "{}", n),
                CellValue::String(s) => write!(f, "{}", s),
                CellValue::Blank(_) => write!(f, ""),
                CellValue::SharedString(s) => write!(f, "{}", s),
            }
        }
    }
    Wrapper(cellvalue)
}

Calling this function and passing a reference to a CellValue will return the value in a printable form.

Effort to get this working on Windows

I would like to get this to work on Windows. May I ask if you ever figured out what went wrong when using the zip-crate and/or did you file any issue there that I can look up to see if it has been resolved or not?

Simple example panics

System:

  • Pop!_OS 20.10
  • Kernel 5.11.0-7614-generic
  • rustc 1.53.0 (53cb7b09b 2021-06-17)

Description

Running the following causes a panic:

cargo build --example simple
./target/debug/examples/simple

Output

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/workbook.rs:162:52
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/workbook.rs:162:52
stack backtrace:
   0:     0x556fd7519a60 - std::backtrace_rs::backtrace::libunwind::trace::ha5edb8ba5c6b7a6c
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
   1:     0x556fd7519a60 - std::backtrace_rs::backtrace::trace_unsynchronized::h0de86d320a827db2
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x556fd7519a60 - std::sys_common::backtrace::_print_fmt::h97b9ad6f0a1380ff
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x556fd7519a60 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h14be7eb08f97fe80
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:46:22
   4:     0x556fd7538c2f - core::fmt::write::h2ca8877d3e0e52de
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/fmt/mod.rs:1094:17
   5:     0x556fd7517e75 - std::io::Write::write_fmt::h64f5987220b618f4
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/io/mod.rs:1584:15
   6:     0x556fd751b6db - std::sys_common::backtrace::_print::h7f1a4097308f2e0a
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:49:5
   7:     0x556fd751b6db - std::sys_common::backtrace::print::h1f799fc2ca7f5035
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:36:9
   8:     0x556fd751b6db - std::panicking::default_hook::{{closure}}::hf38436e8a3ce1071
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:208:50
   9:     0x556fd751b1ad - std::panicking::default_hook::he2f8f3fae11ed1dd
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:225:9
  10:     0x556fd751bced - std::panicking::rust_panic_with_hook::h79a18548bd90c7d4
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:591:17
  11:     0x556fd751b887 - std::panicking::begin_panic_handler::{{closure}}::h212a72cc08e25126
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:497:13
  12:     0x556fd7519efc - std::sys_common::backtrace::__rust_end_short_backtrace::hbd6897dd42bc0fcd
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:141:18
  13:     0x556fd751b7e9 - rust_begin_unwind
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:493:5
  14:     0x556fd749a1b1 - core::panicking::panic_fmt::h77ecd04e9b1dd84d
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/panicking.rs:92:14
  15:     0x556fd749a2a3 - core::result::unwrap_failed::hcbdf25d28ce8f0ca
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/result.rs:1355:5
  16:     0x556fd74bf91a - core::result::Result<T,E>::unwrap::h39afe13a139823ae
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/result.rs:1037:23
  17:     0x556fd74c29fb - simple_excel_writer::workbook::Workbook::close::h5c6403643e12324a
                               at /home/gies/builds/simple_excel_writer/src/workbook.rs:162:28
  18:     0x556fd74c7fd7 - <simple_excel_writer::workbook::Workbook as core::ops::drop::Drop>::drop::hf54a09954fb1e47a
                               at /home/gies/builds/simple_excel_writer/src/workbook.rs:933:13
  19:     0x556fd749fe27 - core::ptr::drop_in_place<simple_excel_writer::workbook::Workbook>::h991a5681393667c8
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/ptr/mod.rs:192:1
  20:     0x556fd749ebe6 - simple::main::ha8a3337af530e293
                               at /home/gies/builds/simple_excel_writer/examples/simple.rs:38:1
  21:     0x556fd749fdab - core::ops::function::FnOnce::call_once::h761e9c0fb9ae8c7a
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/ops/function.rs:227:5
  22:     0x556fd749b94e - std::sys_common::backtrace::__rust_begin_short_backtrace::hd20678986f82c08a
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/sys_common/backtrace.rs:125:18
  23:     0x556fd749b781 - std::rt::lang_start::{{closure}}::h10032dfd13a6b7d6
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/rt.rs:49:18
  24:     0x556fd751c0ea - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hc4354216bf39217c
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/ops/function.rs:259:13
  25:     0x556fd751c0ea - std::panicking::try::do_call::hb68eb312780385cf
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:379:40
  26:     0x556fd751c0ea - std::panicking::try::h22b8e08595060b8b
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:343:19
  27:     0x556fd751c0ea - std::panic::catch_unwind::hc64f1a6a0e71b1fc
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panic.rs:431:14
  28:     0x556fd751c0ea - std::rt::lang_start_internal::h4461fc58637f04f8
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/rt.rs:34:21
  29:     0x556fd749b760 - std::rt::lang_start::h286d7249c33a287d
                               at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/rt.rs:48:5
  30:     0x556fd749f79c - main
  31:     0x7f0e8f055cb2 - __libc_start_main
  32:     0x556fd749a94e - _start
  33:                0x0 - <unknown>
thread panicked while panicking. aborting.
Illegal instruction (core dumped)

Text cells beginning with "=" cannot be created

As far as I can tell, there is currently no way to create a string CellValue that starts with "=" via the API, because such cells will always be interpreted as formulas. A more robust api would be requiring some explicit constructor or function call for formulas, rather than overloading strings for both text content and formulas.

For example,

row!["=A1+B1", "A1+B1"]

could become

row!["A1+B1", formula("A1 + B1") ]

The downside of this, is of course that it would be a breaking API change.

An alternative might be to keep the !row macro working as now, and just change the Row::add_cell API to always treat String as String and add a Formula type, or even to keep that API as well, but add a new function like Row::add_cell_strict. If necessary the row! macro could grow some tag to explicitly disambiguate strings (potentially) starting with "=".

Assuming the above is not mistaken I'd be happy to work on a PR that implements one of these strategies.

Release a new version

Looks like a few features (AutoFilter, etc.) are not released. Is it possible to push a new version to crates.io?

Thanks a lot.

How to convert Vec to row! macro

Hello, I'm using your package to try to write something that calls rust code through python. It will be used to convert Python's pandas into a list and then save it as excel. Because pandas excel is too slow.
However, problems were encountered at the beginning,
I created a set of data (data<Vec<Vec<String>>>), like excel's rows,but I don't how to convert Vec to row! macro

data:
[ [ "a1", "b2", "c3", "d4", "e5", ], [ "11", "12", "13", "14", "15", ], [ "21", "22", "23", "24", "25", ], [ "31", "32", "33", "34", "35", ], ]

function is


fn build_data()->Vec<Vec<String>>{
    let s = "".to_string()
        + "a1,b2,c3,d4,e5\n"
        + "11,12,13,14,15\n"
        + "21,22,23,24,25\n"
        + "31,32,33,34,35";
    
    let s_v:Vec<String> = s.split('\n').map(|x| x.to_string()).collect();
    let mut v:Vec<Vec<String>> = Vec::new();
    for s1 in s_v{
        let s1:Vec<String> = s1.split(',').map(|x| x.to_string()).collect();
        v.push(s1);
    
    }
    v
}

Creating a sheet without calling write_sheet afterwards causing excel detection of corrupted file

If a sheet is created without writing any data to it using the write_sheet method afterwards, excel warns that the file is corrupted and asks whether excel should try to fix it. Normally this can be auto-fixed.

A call to write_sheet without any data actually written will eliminate this excel warning.

example code

let mut wb = Workbook::create("/tmp/b.xlsx");
let mut _sheet = wb.create_sheet("SheetName");
wb.close().expect("close excel error!");

Failure during file creation does not report error, but panics.

Thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 32, kind: Other, message: "Proces nemá přístup k souboru, neboť jej právě využívá jiný proces." }', ...\simple_excel_writer-0.1.7\src\workbook.rs:128:52

IMO there unwrap should be replaced with ?.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.