use std::fs::File;
use std::io::Cursor;
use std::path::Path;
use crate::error::{Error, Result};
#[derive(Debug)]
pub enum OfficeDocument {
#[cfg(feature = "word")]
Word(Box<word_ooxml::Document>),
#[cfg(feature = "excel")]
Excel(excel_ooxml::Workbook),
#[cfg(feature = "powerpoint")]
Powerpoint(powerpoint_ooxml::Presentation),
}
impl OfficeDocument {
pub fn save_to_file(&self, path: impl AsRef<Path>) -> Result<()> {
match self {
#[cfg(feature = "word")]
OfficeDocument::Word(document) => document.save_to_file(path),
#[cfg(feature = "excel")]
OfficeDocument::Excel(workbook) => workbook.save_to_file(path),
#[cfg(feature = "powerpoint")]
OfficeDocument::Powerpoint(presentation) => presentation.save_to_file(path),
}
}
}
pub fn open(path: impl AsRef<Path>) -> Result<OfficeDocument> {
let bytes = std::fs::read(path)?;
let package = opc::Package::read_from(Cursor::new(&bytes))?;
if package.part("/word/document.xml").is_some() {
#[cfg(feature = "word")]
return Ok(OfficeDocument::Word(Box::new(
word_ooxml::Document::read_from(Cursor::new(&bytes))?,
)));
#[cfg(not(feature = "word"))]
return Err(Error::FormatNotEnabled("word"));
}
if package.part("/xl/workbook.xml").is_some() {
#[cfg(feature = "excel")]
return Ok(OfficeDocument::Excel(excel_ooxml::Workbook::read_from(
Cursor::new(&bytes),
)?));
#[cfg(not(feature = "excel"))]
return Err(Error::FormatNotEnabled("excel"));
}
if package.part("/ppt/presentation.xml").is_some() {
#[cfg(feature = "powerpoint")]
return Ok(OfficeDocument::Powerpoint(
powerpoint_ooxml::Presentation::read_from(Cursor::new(&bytes))?,
));
#[cfg(not(feature = "powerpoint"))]
return Err(Error::FormatNotEnabled("powerpoint"));
}
Err(Error::UnrecognizedFormat)
}
pub trait OpenFile: Sized {
fn open_file(path: impl AsRef<Path>) -> Result<Self>;
}
pub trait SaveToFile {
fn save_to_file(&self, path: impl AsRef<Path>) -> Result<()>;
}
#[cfg(feature = "word")]
impl OpenFile for word_ooxml::Document {
fn open_file(path: impl AsRef<Path>) -> Result<Self> {
Ok(Self::read_from(File::open(path)?)?)
}
}
#[cfg(feature = "word")]
impl SaveToFile for word_ooxml::Document {
fn save_to_file(&self, path: impl AsRef<Path>) -> Result<()> {
self.write_to(File::create(path)?)?;
Ok(())
}
}
#[cfg(feature = "excel")]
impl OpenFile for excel_ooxml::Workbook {
fn open_file(path: impl AsRef<Path>) -> Result<Self> {
Ok(Self::read_from(File::open(path)?)?)
}
}
#[cfg(feature = "excel")]
impl SaveToFile for excel_ooxml::Workbook {
fn save_to_file(&self, path: impl AsRef<Path>) -> Result<()> {
self.write_to(File::create(path)?)?;
Ok(())
}
}
#[cfg(feature = "powerpoint")]
impl OpenFile for powerpoint_ooxml::Presentation {
fn open_file(path: impl AsRef<Path>) -> Result<Self> {
Ok(Self::read_from(File::open(path)?)?)
}
}
#[cfg(feature = "powerpoint")]
impl SaveToFile for powerpoint_ooxml::Presentation {
fn save_to_file(&self, path: impl AsRef<Path>) -> Result<()> {
self.write_to(File::create(path)?)?;
Ok(())
}
}