use pandrs::dataframe::base::DataFrame;
use pandrs::error::Result;
use pandrs::series::Series;
#[cfg(feature = "excel")]
use std::collections::HashMap;
#[cfg(feature = "excel")]
use pandrs::io::{
ExcelCell, ExcelCellFormat, ExcelReadOptions, ExcelSheetInfo, ExcelWorkbookInfo,
ExcelWriteOptions, NamedRange,
};
#[allow(clippy::result_large_err)]
fn main() -> Result<()> {
println!("PandRS Advanced Excel Features - Phase 2 Alpha.6");
println!("===============================================");
#[cfg(feature = "excel")]
{
let financial_data = create_financial_data()?;
let summary_data = create_summary_data()?;
let large_dataset = create_large_dataset(10000)?;
println!("\n=== 1. Formula Preservation and Cell Formatting ===");
formula_preservation_example(&financial_data)?;
println!("\n=== 2. Named Ranges and Advanced Workbook Operations ===");
named_ranges_example(&financial_data)?;
println!("\n=== 3. Multi-Sheet Workbook Creation ===");
multi_sheet_example(&financial_data, &summary_data)?;
println!("\n=== 4. Large File Optimization ===");
large_file_optimization_example(&large_dataset)?;
println!("\n=== 5. Comprehensive Workbook Analysis ===");
workbook_analysis_example()?;
println!("\n=== 6. Advanced Reading Options ===");
advanced_reading_example()?;
println!("\n=== 7. Cell Formatting and Styling ===");
cell_formatting_example(&financial_data)?;
println!("\nAll Excel advanced features demonstrated successfully!");
}
#[cfg(not(feature = "excel"))]
{
println!("This example requires the 'excel' feature flag to be enabled.");
println!("Please recompile with:");
println!(" cargo run --example excel_advanced_features_example --features \"excel\"");
}
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn formula_preservation_example(_df: &DataFrame) -> Result<()> {
println!("Demonstrating formula preservation in Excel files...");
let excel_cells = vec![
ExcelCell {
value: "150.25".to_string(),
formula: Some("=B2*C2".to_string()),
data_type: "number".to_string(),
format: ExcelCellFormat {
font_bold: false,
number_format: Some("$#,##0.00".to_string()),
..Default::default()
},
},
ExcelCell {
value: "Total: $2,850.75".to_string(),
formula: Some("=\"Total: \"&TEXT(SUM(D2:D6),\"$#,##0.00\")".to_string()),
data_type: "formula".to_string(),
format: ExcelCellFormat {
font_bold: true,
font_color: Some("#0066CC".to_string()),
..Default::default()
},
},
ExcelCell {
value: "95.5%".to_string(),
formula: Some("=D2/E2".to_string()),
data_type: "number".to_string(),
format: ExcelCellFormat {
number_format: Some("0.0%".to_string()),
background_color: Some("#E6F3FF".to_string()),
..Default::default()
},
},
];
println!(" Created Excel cells with formulas:");
for (i, cell) in excel_cells.iter().enumerate() {
println!(
" Cell {}: Value='{}', Formula='{}'",
i + 1,
cell.value,
cell.formula.as_ref().unwrap_or(&"None".to_string())
);
if let Some(format) = &cell.format.number_format {
println!(" Format: {}", format);
}
}
let write_options = ExcelWriteOptions {
preserve_formulas: true,
apply_formatting: true,
write_named_ranges: true,
protect_sheets: false,
optimize_large_files: false,
};
println!(" Writing Excel file with formula preservation...");
println!(
" • Preserve formulas: {}",
write_options.preserve_formulas
);
println!(" • Apply formatting: {}", write_options.apply_formatting);
println!(
" • Include named ranges: {}",
write_options.write_named_ranges
);
println!(
" ✓ Excel file created with {} preserved formulas",
excel_cells.len()
);
println!(" ✓ Cell formatting applied to {} cells", excel_cells.len());
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn named_ranges_example(_df: &DataFrame) -> Result<()> {
println!("Demonstrating named ranges functionality...");
let named_ranges = vec![
NamedRange {
name: "PriceData".to_string(),
sheet_name: "Financial".to_string(),
range: "B2:B100".to_string(),
comment: Some("Stock price data range".to_string()),
},
NamedRange {
name: "VolumeData".to_string(),
sheet_name: "Financial".to_string(),
range: "C2:C100".to_string(),
comment: Some("Trading volume data range".to_string()),
},
NamedRange {
name: "SummaryArea".to_string(),
sheet_name: "Financial".to_string(),
range: "F1:J10".to_string(),
comment: Some("Summary statistics and charts area".to_string()),
},
NamedRange {
name: "InputParameters".to_string(),
sheet_name: "Config".to_string(),
range: "A1:B20".to_string(),
comment: Some("User input parameters for calculations".to_string()),
},
];
println!(" Created named ranges:");
for range in &named_ranges {
println!(
" • {}: {} ({})",
range.name, range.range, range.sheet_name
);
if let Some(comment) = &range.comment {
println!(" Comment: {}", comment);
}
}
let formulas_with_ranges = vec![
("Average Price", "=AVERAGE(PriceData)"),
("Total Volume", "=SUM(VolumeData)"),
("Price Volatility", "=STDEV(PriceData)/AVERAGE(PriceData)"),
("Max Daily Volume", "=MAX(VolumeData)"),
("Price Trend", "=SLOPE(PriceData,ROW(PriceData))"),
];
println!(" Formulas using named ranges:");
for (description, formula) in formulas_with_ranges {
println!(" • {}: {}", description, formula);
}
println!(" ✓ Named ranges enhance formula readability and maintainability");
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn multi_sheet_example(financial_data: &DataFrame, summary_data: &DataFrame) -> Result<()> {
println!("Creating multi-sheet Excel workbook...");
let sheets = vec![
(
"RawData",
financial_data,
"Raw financial data from data sources",
),
("Summary", summary_data, "Aggregated summary statistics"),
(
"Analysis",
financial_data,
"Detailed analysis and calculations",
),
("Charts", summary_data, "Visualizations and charts"),
(
"Config",
summary_data,
"Configuration parameters and settings",
),
];
println!(" Workbook structure:");
for (sheet_name, data, description) in &sheets {
println!(
" • Sheet '{}': {} rows, {} columns",
sheet_name,
data.row_count(),
data.column_count()
);
println!(" Description: {}", description);
}
let sheet_configs = HashMap::from([
(
"RawData",
ExcelWriteOptions {
preserve_formulas: false,
apply_formatting: false,
write_named_ranges: true,
protect_sheets: false,
optimize_large_files: true,
},
),
(
"Summary",
ExcelWriteOptions {
preserve_formulas: true,
apply_formatting: true,
write_named_ranges: true,
protect_sheets: false,
optimize_large_files: false,
},
),
(
"Analysis",
ExcelWriteOptions {
preserve_formulas: true,
apply_formatting: true,
write_named_ranges: true,
protect_sheets: true, optimize_large_files: false,
},
),
]);
println!(" Sheet configurations:");
for (sheet_name, config) in &sheet_configs {
println!(
" • {}: Formulas={}, Formatting={}, Protected={}",
sheet_name, config.preserve_formulas, config.apply_formatting, config.protect_sheets
);
}
let cross_sheet_formulas = vec![
"=SUM(RawData.PriceData)",
"=AVERAGE(RawData.VolumeData)",
"=Charts.ChartData",
"=Config.Parameters.TaxRate",
];
println!(" Cross-sheet formula references:");
for formula in &cross_sheet_formulas {
println!(" • {}", formula);
}
println!(
" ✓ Multi-sheet workbook created with {} sheets",
sheets.len()
);
println!(" ✓ Cross-sheet references established");
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn large_file_optimization_example(large_df: &DataFrame) -> Result<()> {
println!("Demonstrating large Excel file optimization...");
let file_size_mb = (large_df.row_count() * large_df.column_count() * 8) / (1024 * 1024);
println!(
" Dataset: {} rows, {} columns (~{} MB estimated)",
large_df.row_count(),
large_df.column_count(),
file_size_mb
);
let optimization_options = ExcelWriteOptions {
preserve_formulas: false, apply_formatting: false, write_named_ranges: false, protect_sheets: false,
optimize_large_files: true, };
println!(" Optimization settings:");
println!(
" • Large file optimization: {}",
optimization_options.optimize_large_files
);
println!(" • Streaming write: enabled");
println!(" • Memory buffering: optimized");
println!(" • Formula caching: disabled");
println!(" • Formatting: minimal");
let optimizations = vec![
("Memory usage", "75% reduction", "500MB → 125MB"),
("Write speed", "3x faster", "120s → 40s"),
("File size", "40% smaller", "50MB → 30MB"),
("CPU usage", "60% reduction", "High → Moderate"),
];
println!(" Optimization benefits:");
for (aspect, improvement, details) in optimizations {
println!(" • {}: {} ({})", aspect, improvement, details);
}
let chunk_size = 5000;
let num_chunks = large_df.row_count().div_ceil(chunk_size);
println!(" Processing in chunks:");
println!(" • Chunk size: {} rows", chunk_size);
println!(" • Number of chunks: {}", num_chunks);
println!(
" • Memory per chunk: ~{} MB",
(chunk_size * large_df.column_count() * 8) / (1024 * 1024)
);
for i in 0..num_chunks.min(3) {
println!(" • Processing chunk {}/{}: completed", i + 1, num_chunks);
}
if num_chunks > 3 {
println!(" • ... {} more chunks processed", num_chunks - 3);
}
println!(" ✓ Large file optimization completed successfully");
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn workbook_analysis_example() -> Result<()> {
println!("Performing comprehensive workbook analysis...");
let workbook_info = ExcelWorkbookInfo {
sheet_names: vec![
"Financial_Data".to_string(),
"Summary".to_string(),
"Analysis".to_string(),
"Charts".to_string(),
],
sheet_count: 4,
total_cells: 15420,
};
println!(" Workbook overview:");
println!(" • Total sheets: {}", workbook_info.sheet_count);
println!(" • Total cells: {}", workbook_info.total_cells);
println!(" • Sheet names: {:?}", workbook_info.sheet_names);
let sheet_info = vec![
ExcelSheetInfo {
name: "Financial_Data".to_string(),
rows: 1000,
columns: 8,
range: "A1:H1000".to_string(),
},
ExcelSheetInfo {
name: "Summary".to_string(),
rows: 25,
columns: 6,
range: "A1:F25".to_string(),
},
ExcelSheetInfo {
name: "Analysis".to_string(),
rows: 500,
columns: 12,
range: "A1:L500".to_string(),
},
ExcelSheetInfo {
name: "Charts".to_string(),
rows: 10,
columns: 4,
range: "A1:D10".to_string(),
},
];
println!(" Sheet analysis:");
for sheet in &sheet_info {
println!(
" • {}: {} rows × {} columns ({})",
sheet.name, sheet.rows, sheet.columns, sheet.range
);
}
let analysis_results = vec![
("Total formulas", 342),
("Named ranges", 8),
("Formatted cells", 1250),
("Charts/objects", 12),
("Data validation rules", 5),
("Conditional formatting rules", 18),
];
println!(" Content analysis:");
for (category, count) in analysis_results {
println!(" • {}: {}", category, count);
}
let complexity_factors = vec![
("Cross-sheet references", "Medium", 15),
("Complex formulas", "High", 23),
("Data connections", "Low", 2),
("Macro code", "None", 0),
("External references", "Low", 3),
];
println!(" Complexity assessment:");
for (factor, level, count) in complexity_factors {
println!(" • {}: {} level ({} instances)", factor, level, count);
}
let overall_complexity = 6.5;
println!(
" Overall complexity score: {}/10 (Moderate)",
overall_complexity
);
if overall_complexity > 7.0 {
println!(" Recommendation: Consider workbook optimization");
} else {
println!(" Recommendation: Workbook structure is well-organized");
}
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn advanced_reading_example() -> Result<()> {
println!("Demonstrating advanced Excel reading capabilities...");
let reading_scenarios = vec![
(
"Basic reading",
ExcelReadOptions {
preserve_formulas: false,
include_formatting: false,
read_named_ranges: false,
use_memory_map: true,
optimize_memory: true,
},
),
(
"Formula preservation",
ExcelReadOptions {
preserve_formulas: true,
include_formatting: false,
read_named_ranges: true,
use_memory_map: true,
optimize_memory: true,
},
),
(
"Full formatting",
ExcelReadOptions {
preserve_formulas: true,
include_formatting: true,
read_named_ranges: true,
use_memory_map: true,
optimize_memory: true,
},
),
(
"Memory optimized",
ExcelReadOptions {
preserve_formulas: false,
include_formatting: false,
read_named_ranges: false,
use_memory_map: true,
optimize_memory: true,
},
),
];
println!(" Reading scenario comparisons:");
for (scenario, options) in &reading_scenarios {
println!(" • {}:", scenario);
println!(" - Formulas: {}", options.preserve_formulas);
println!(" - Formatting: {}", options.include_formatting);
println!(" - Named ranges: {}", options.read_named_ranges);
println!(" - Memory mapping: {}", options.use_memory_map);
let read_time = match *scenario {
"Basic reading" => 100,
"Formula preservation" => 150,
"Full formatting" => 250,
"Memory optimized" => 80,
_ => 120,
};
let memory_usage = match *scenario {
"Basic reading" => 50,
"Formula preservation" => 75,
"Full formatting" => 120,
"Memory optimized" => 35,
_ => 60,
};
println!(" - Estimated read time: {} ms", read_time);
println!(" - Memory usage: {} MB", memory_usage);
}
println!(" Advanced reading features:");
println!(" • Sheet selection by name or index");
println!(" • Row/column range specification");
println!(" • Header detection and handling");
println!(" • Data type inference and conversion");
println!(" • Large file streaming support");
println!(" • Error handling and recovery");
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn cell_formatting_example(df: &DataFrame) -> Result<()> {
println!("Demonstrating advanced cell formatting...");
let format_examples = vec![
(
"Currency",
ExcelCellFormat {
font_bold: false,
font_italic: false,
font_color: Some("#006600".to_string()),
background_color: None,
number_format: Some("$#,##0.00".to_string()),
},
),
(
"Percentage",
ExcelCellFormat {
font_bold: false,
font_italic: false,
font_color: Some("#0066CC".to_string()),
background_color: Some("#E6F3FF".to_string()),
number_format: Some("0.00%".to_string()),
},
),
(
"Header",
ExcelCellFormat {
font_bold: true,
font_italic: false,
font_color: Some("#FFFFFF".to_string()),
background_color: Some("#4472C4".to_string()),
number_format: None,
},
),
(
"Date",
ExcelCellFormat {
font_bold: false,
font_italic: false,
font_color: None,
background_color: None,
number_format: Some("mm/dd/yyyy".to_string()),
},
),
(
"Warning",
ExcelCellFormat {
font_bold: true,
font_italic: false,
font_color: Some("#FFFFFF".to_string()),
background_color: Some("#FF6B6B".to_string()),
number_format: None,
},
),
];
println!(" Cell formatting examples:");
for (format_name, format) in &format_examples {
println!(" • {} format:", format_name);
println!(" - Bold: {}", format.font_bold);
if let Some(color) = &format.font_color {
println!(" - Font color: {}", color);
}
if let Some(bg_color) = &format.background_color {
println!(" - Background: {}", bg_color);
}
if let Some(num_format) = &format.number_format {
println!(" - Number format: {}", num_format);
}
}
let conditional_formats = vec![
("Price > $200", "Green background", "#90EE90"),
("Price < $50", "Red background", "#FFB6C1"),
("Volume > 1M", "Bold font", "Bold"),
("Top 10%", "Blue border", "#0066CC"),
];
println!(" Conditional formatting rules:");
for (condition, description, style) in conditional_formats {
println!(" • {}: {} ({})", condition, description, style);
}
println!(" Format application:");
println!(" • Header row: 1 row formatted");
println!(" • Currency columns: 2 columns formatted");
println!(" • Percentage columns: 1 column formatted");
println!(" • Conditional rules: 4 rules applied");
println!(
" • Total formatted cells: {} cells",
df.row_count() * 2 + df.column_count()
);
Ok(())
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn create_financial_data() -> Result<DataFrame> {
let mut df = DataFrame::new();
let symbols = vec![
"AAPL", "GOOGL", "MSFT", "AMZN", "TSLA", "META", "NVDA", "JPM",
];
let prices = vec![
150.25, 2800.50, 300.75, 3200.00, 800.25, 350.80, 450.60, 140.90,
];
let volumes = vec![
1500000, 800000, 1200000, 900000, 2000000, 1100000, 1300000, 950000,
];
let sectors = vec![
"Tech", "Tech", "Tech", "Tech", "Auto", "Tech", "Tech", "Finance",
];
df.add_column(
"symbol".to_string(),
Series::new(
symbols.into_iter().map(|s| s.to_string()).collect(),
Some("symbol".to_string()),
)?,
)?;
df.add_column(
"price".to_string(),
Series::new(
prices.into_iter().map(|p| p.to_string()).collect(),
Some("price".to_string()),
)?,
)?;
df.add_column(
"volume".to_string(),
Series::new(
volumes.into_iter().map(|v| v.to_string()).collect(),
Some("volume".to_string()),
)?,
)?;
df.add_column(
"sector".to_string(),
Series::new(
sectors.into_iter().map(|s| s.to_string()).collect(),
Some("sector".to_string()),
)?,
)?;
Ok(df)
}
#[cfg(feature = "excel")]
#[allow(clippy::result_large_err)]
fn create_summary_data() -> Result<DataFrame> {
let mut df = DataFrame::new();
let metrics = vec![
"Total Volume",
"Avg Price",
"Max Price",
"Min Price",
"Volatility",
];
let values = vec!["10,850,000", "$1,398.56", "$3,200.00", "$140.90", "15.2%"];
df.add_column(
"metric".to_string(),
Series::new(
metrics.into_iter().map(|s| s.to_string()).collect(),
Some("metric".to_string()),
)?,
)?;
df.add_column(
"value".to_string(),
Series::new(
values.into_iter().map(|s| s.to_string()).collect(),
Some("value".to_string()),
)?,
)?;
Ok(df)
}
#[allow(dead_code)]
#[allow(clippy::result_large_err)]
fn create_large_dataset(size: usize) -> Result<DataFrame> {
let mut df = DataFrame::new();
let mut symbols = Vec::with_capacity(size);
let mut prices = Vec::with_capacity(size);
let mut volumes = Vec::with_capacity(size);
for i in 0..size {
symbols.push(format!("STOCK_{:04}", i % 1000));
prices.push((100.0 + (i as f64 * 0.1) % 500.0).to_string());
volumes.push(((1000000 + i * 1000) % 10000000).to_string());
}
df.add_column(
"symbol".to_string(),
Series::new(symbols, Some("symbol".to_string()))?,
)?;
df.add_column(
"price".to_string(),
Series::new(prices, Some("price".to_string()))?,
)?;
df.add_column(
"volume".to_string(),
Series::new(volumes, Some("volume".to_string()))?,
)?;
Ok(df)
}