use std::io::{Cursor, Write};
pub fn build_zip(entries: &[(&str, &[u8])]) -> Vec<u8> {
let mut buf = Vec::new();
{
let mut writer = zip::ZipWriter::new(Cursor::new(&mut buf));
let options = zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Deflated);
for (name, data) in entries {
writer.start_file(*name, options).unwrap();
writer.write_all(data).unwrap();
}
writer.finish().unwrap();
}
buf
}
pub fn build_zip_owned(entries: &[(String, Vec<u8>)]) -> Vec<u8> {
let borrowed: Vec<(&str, &[u8])> = entries
.iter()
.map(|(name, data)| (name.as_str(), data.as_slice()))
.collect();
build_zip(&borrowed)
}
pub fn rels_xml(relationships: &[(&str, &str, &str)]) -> String {
let mut xml = String::from(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n",
);
for (id, type_suffix, target) in relationships {
xml.push_str(&format!(
" <Relationship Id=\"{id}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/{type_suffix}\" Target=\"{target}\"/>\n"
));
}
xml.push_str("</Relationships>");
xml
}
pub fn workbook_xml(sheets: &[(&str, &str, Option<&str>)]) -> String {
let mut xml = String::from(
"<?xml version=\"1.0\"?>\n\
<workbook xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets>\n",
);
for (name, r_id, state) in sheets {
let state_attr = match state {
Some(s) => format!(" state=\"{s}\""),
None => String::new(),
};
xml.push_str(&format!(
" <sheet name=\"{name}\" sheetId=\"1\" r:id=\"{r_id}\"{state_attr}/>\n"
));
}
xml.push_str(" </sheets>\n</workbook>");
xml
}
pub fn worksheet_xml(rows_xml: &str, merge_cells_xml: &str) -> String {
format!("<worksheet><sheetData>\n{rows_xml}\n</sheetData>{merge_cells_xml}</worksheet>")
}
pub const DEFAULT_STYLES_XML: &[u8] =
br#"<styleSheet><cellXfs><xf numFmtId="0"/></cellXfs></styleSheet>"#;
pub const DATE_STYLES_XML: &[u8] =
br#"<styleSheet><cellXfs><xf numFmtId="0"/><xf numFmtId="14"/></cellXfs></styleSheet>"#;
pub const FONT_STYLES_XML: &[u8] = br#"<styleSheet>
<fonts count="2">
<font><sz val="11"/><name val="Calibri"/></font>
<font><b/><sz val="14"/><name val="Calibri"/></font>
</fonts>
<cellXfs><xf fontId="0"/><xf fontId="1"/></cellXfs>
</styleSheet>"#;
pub fn shared_strings_xml(strings: &[&str]) -> String {
let mut xml = format!(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\
<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"{0}\" uniqueCount=\"{0}\">\n",
strings.len()
);
for s in strings {
xml.push_str(&format!(" <si><t>{s}</t></si>\n"));
}
xml.push_str("</sst>");
xml
}