Несколько лет назад я работал с Excel в приложении С#, чтобы создать отчет со статистическими данными. Это было приложение WPF с .Net Framework 4.0, которое позволяет мне обрабатывать некоторые данные, рассчитывать статистические параметры и создавать отчет в Excel.
Я использовал COM-библиотеку Microsoft.Office.Interop.Excel версии 11 для работы с форматом Excel-2003. Итак, теперь у меня есть цель переписать это приложение, используя Net Core 3.1. У меня сейчас есть некоторые ограничения для программирования: версия ОС и версия Excel (Win 7 и Excel 2003).
Также я стараюсь, чтобы мой код был как можно ближе к оригиналу. Я исследовал и обнаружил, что приложу много усилий, если решу переписать эту часть приложения, в которой использовался Excel, с использованием какой-либо библиотеки (например, Epplus). Некоторые библиотеки не бесплатны или их бесплатные версии сильно ограничены. Также популярный Epplus не предоставляет функциональности, которая мне нужна для настройки моих диаграмм Excel. Например, я обнаружил, что в Epplus я не могу настроить ориентацию текстовых меток и линии сетки для осей, которые предопределены для определенных типов диаграмм. Итак, моя цель — интегрировать старую версию Microsoft.Office.Interop.Excel в мое решение dotnet core 3.1.
Но я столкнулся с проблемой во время этого. Я предоставил часть кода ниже. Когда выполнение попадает в строку с Диапазон range1 = ws.Range[ws.Cells[курсор, i], ws.Cells[курсор, i]], я получаю исключение Индекс вне допустимого диапазона, которое происходит в библиотеке COM, и эта ошибка приводит меня в полное недоумение. В моем коде ничего не изменилось, чтобы вызвать эту ошибку. Старая версия приложения с Net Framework 4.0 работает должным образом с теми же входными данными. Я даже обнаружил, что если я перейду на Net Framework 4.8 и добавлю ссылку на эту COM-библиотеку excel v.11, у меня не будет этой ошибки. Так что мое приложение не работает только в среде Net Core. Дурацкая затея, но может то, что в новых версиях c# теперь есть System.Range и это как-то влияет на это? Я так не думаю, но...
Я не могу понять, почему это происходит, и мне становится грустно. Может ли кто-нибудь помочь мне, как я могу исправить эту ошибку? Благодарен за любую помощь в этом вопросе.
using Microsoft.Office.Interop.Excel;
using System;
using System.Diagnostics;
using System.Linq;
using WpfStatistica.Events;
using WpfStatistica.Statistic;
using Range = Microsoft.Office.Interop.Excel.Range;
namespace WpfStatistica.Excel.Old
{
public class ExelCreator
{
private readonly StatistCollector _statData;
private readonly string _filePath;
private Application _excel;
private Workbook _workbook;
private Sheets _sheets;
public ExelCreator(StatistCollector statData, string filePath)
{
_statData = statData;
_filePath = filePath;
}
public void CreateExcelFile()
{
_excel = new Application();
_excel.Visible = false;
_excel.SheetsInNewWorkbook = 4;
_workbook = _excel.Workbooks.Add();
_sheets = _excel.Worksheets;
ProcessFirstSheet();
ProcessSecondSheet();
ProcessThirdSheet();
ProcessFourthSheet();
_workbook.SaveAs(_filePath, 1);
_excel.Quit();
}
private void ProcessFirstSheet()
{
Worksheet ws = _excel.Worksheets[1];
ws.Name = "Types of failures";
// Place columns names
ws.Cells[1, 1] = "Test";
// Some code here
ws.Cells[1, 34] = "StdErr";
//Stat params output
for (int i = 0; i < _statData.TestNum.Count; i++)
{
ws.Cells[i + 2, 1] = _statData.TestNum[i];
// Some code here
}
// Create table with info
int kursor = _statData.TestNum.Count + 5;
Range range = null;
for (int i = 1; i <= 9; i++)
{
Range range1 = ws.Range[ws.Cells[kursor, i], ws.Cells[kursor, i]]; //=> Get Index out of range error here
Range range2 = ws.Range[ws.Cells[kursor - 1, i], ws.Cells[kursor - 1, i]];
range = ws.Range[range1, range2];
if (i == 1 || i == 2 || i == 4 || i == 7)
{
range.Merge();
range.Font.Bold = true;
}
range.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
range.Borders[XlBordersIndex.xlEdgeTop].LineStyle = 1;
range.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = 1;
range.Borders[XlBordersIndex.xlEdgeRight].LineStyle = 1;
range.HorizontalAlignment = XlHAlign.xlHAlignCenter;
range.VerticalAlignment = XlVAlign.xlVAlignCenter;
range1.Font.Bold = true;
}
// The rest of the code for working with filling in the table and creating a Pareto chart
}
// Other methods
}
}
@RobertHarvey, нет, в этой строке есть что-то вроде ws.Range[ws.Cells[100, 10], ws.Cells[100, 10]].
Обратите внимание, что .Cells[]
должен возвращать Range
, ws.Range[cell, cell]
кажется излишним.
Для моей цели я должен использовать диапазон, который состоит не только из одной ячейки, но из некоторой группы ячеек, поэтому индексатор диапазона должен получать два объекта диапазона: «диапазон от», «диапазон до»
В предыдущей версии эта конструкция Range range1 = ws.Range[ws.Cells[kursor, i], ws.Cells[kursor, i]] работала как положено, но теперь я должен явно приводить ws.Cells[kursor, i]. Так что это работает с (Range)ws.Cells[kursor, i].
Excel 2003 32-битный. Может быть, вы попали в максимальное количество строк?