Warning when using c# to generate an excel file with hidden rows

43 views Asked by At

When attempting to open an excel file my application generates with hidden rows I get the following warning message.

We found a problem with some content in 'all-harvests.xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook click Yes.

If you click 'Yes' then the expected output is displayed with all rows appropriately hidden.

In my web app I am generating an excel file with rows containing harvest information. The file then gets sent as an email attachment to different wildlife management authorities. I am trying to hide any rows that have a "Harvested" date outside of the current hunting season (Sept-Feb). The logic of determining whether to hide vs show the row works but the generated excel file displays the above warning.

If I remove the portion that hides rows (FilterExcelFile), then the Excel file is generated and can be opened without any issue. I have tried changing the file type to xls which resulted in a completely unreadable file. I also have looked up similar posts on Stackoverflow but haven't been able to get it working based off of those answers. I appreciate any assistance you might have as I am at a loss for what to try next.

The file is generated here:

private byte[] GenerateExcelFile(IEnumerable<HarvestSpreadsheetDataRow> data)
{
    // Create Excel file with all harvested data
    const string sheetName = "Harvest_Report";
    var bytes = new PackageBuilder().WithWorksheet(w => w
                .WithName(sheetName)
                .WithTable<HarvestSpreadsheetDataRow>(t => t.WithData(data).IgnoreColumn(r => r.HarvestId))
                .AutoFit()
            ).ToByteArray();

    return bytes;
}

The row hiding takes place in this function

private byte[] FilterExcelFile(byte[] excelBytes)
{
    using (MemoryStream stream = new MemoryStream(excelBytes))
    {
        using (ExcelPackage package = new ExcelPackage(stream))
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.FirstOrDefault();

            if (worksheet != null)
            {
                // Find the index of the "Harvested" Date
                int harvestedDateColumnIndex = 4;

                // Get the total number of rows in the worksheet
                int rowCount = worksheet.Dimension.Rows;

                // Get the current date
                DateTime currentDate = _dateTimeProvider.Now;

                // Determine the hunting season range for the current year
                DateTime huntingSeasonStart = new DateTime(currentDate.Month >= 9 ? currentDate.Year : currentDate.Year - 1, 9, 1); // September 1st
                DateTime huntingSeasonEnd = new DateTime(currentDate.Month <= 2 ? currentDate.Year : currentDate.Year + 1, 2, 28).AddDays(1); // February 28th (or 29th in a leap year) + 1 day

                for (int row = 2; row <= rowCount; row++)
                {
                     var cellValue = worksheet.Cells[row, harvestedDateColumnIndex].Value;

                     if (cellValue != null && DateTime.TryParse(cellValue.ToString(), out DateTime harvestedDate))
                     {
                         if (!(harvestedDate >= huntingSeasonStart && harvestedDate < huntingSeasonEnd))
                         {
                             worksheet.Row(row).Hidden = true; // Hide rows with harvest dates outside the current hunting season
                         }
                     }
                 }

                 // Save the changes to the memory stream
                 package.Save();
             }

             return package.GetAsByteArray();
         }
     }
}

This function is where the other two are called and the excel file is sent as an email attachment:

public void SendReportEmail(string toEmailAddress, string subject, string message, string homeAddress)
{
    if (string.IsNullOrWhiteSpace(toEmailAddress))
        throw new ArgumentNullException(nameof(toEmailAddress));

    // Retrieve completed harvests data
    List<Harvest> harvests = _harvestService.GetCompletedHarvests();

    // Convert data to HarvestSpreadsheetDataRow objects
    var data = harvests.Select(h => new HarvestSpreadsheetDataRow(h));

    // Create Excel file with all harvested data
    byte[] excelBytes = GenerateExcelFile(data);

    // Modify Excel file to hide rows not within the current hunting season
    byte[] filteredExcelBytes = FilterExcelFile(excelBytes);

    // Attach Excel file to the email
    var attachment = new EasyAttachment
            {
                FileName = $"all-harvests.xlsx",
                ContentStream = new MemoryStream(filteredExcelBytes)
            };
    var attachments = new List<EasyAttachment> { attachment };

    // Serialize email body with subject, message, and home address
    var year = DateTime.Now.Year.ToString();
    var body = _emailTemplateService.SerializeHtml(subject, message, homeAddress, year);

    // Create and send email with attached Excel file
    var easyMessage = new EasyMessage("[email protected]", toEmailAddress)
            {
                Subject = subject,
                Body = body,
                IsBodyHtml = true,
                Attachments = attachments
            };

    _easyEmailer.Send(easyMessage);
}
0

There are 0 answers