Мне нужно создать файл Excel xlsx. Итак, я решил использовать Open xml (Open Xml 2.0, потому что мне нужно использовать .net 3.5).Использование Open Xml для создания xlsx-файла для Excel 2013
После некоторых исследований о Open XML, я создал этот класс:
public class ExcelFileManager : FileManager
{
private SpreadsheetDocument _package;
private Row _currentRow;
private SheetData _sheetData;
private int? _cellColumnN2;
private int _cellColumnN1;
private int _cellRow;
public ExcelFileManager(string path)
: base(path)
{
_package = SpreadsheetDocument.Create(path, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
_cellColumnN1 = 65;
_cellRow = 1;
CreateSpreadSheet();
}
private void CreateSpreadSheet()
{
var workbookPart1 = _package.AddWorkbookPart();
workbookPart1.Workbook = new Workbook();
var worksheetPart1 = workbookPart1.AddNewPart<WorksheetPart>();
worksheetPart1.Worksheet = new Worksheet();
var sheets = _package.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
var sheet = new Sheet()
{
Id = _package.WorkbookPart.
GetIdOfPart(worksheetPart1),
SheetId = 1,
Name = "Users"
};
sheets.Append(sheet);
_sheetData = new SheetData();
_currentRow = new Row();
_sheetData.Append(_currentRow);
worksheetPart1.Worksheet.Append(_sheetData);
}
public override void AddHeader(IEnumerable<string> columnsName)
{
if (columnsName == null || !columnsName.Any())
throw new ArgumentNullException("columnsName");
try
{
AddRow(columnsName.ToArray());
}
catch (Exception e)
{
Tracing.Application.TraceError(-1, "An error occured when adding header to excel file", e);
throw;
}
}
public override void AddRow(params object[] values)
{
if (values == null || !values.Any())
throw new ArgumentNullException("values");
try
{
var listCells = new List<OpenXmlElement>();
foreach (var item in values)
{
listCells.Add(CreateCellRow(item));
}
_currentRow.Append(listCells);
AddNewRow();
}
catch (Exception e)
{
Tracing.Application.TraceError(-1, "An error occured when adding row to excel file", e);
throw;
}
}
public override void AddCell(object value)
{
try
{
var cell = CreateCellRow(value);
_currentRow.Append(cell);
}
catch (Exception e)
{
Tracing.Application.TraceError(-1, "An error occured when adding cell to excel file", e);
throw;
}
}
public override void AddNewRow()
{
_currentRow = new Row();
_sheetData.Append(_currentRow);
IncreaseRow();
}
#region Utils
private Cell CreateCellRow(object value)
{
Tracing.Application.TraceInformation("Add value \"{0}\" in cell {1}", value, GetCellLocation());
Cell cell = new Cell();
if (value == null)
{
cell.CellValue = new CellValue(string.Empty);
cell.DataType = CellValues.String;
}
else
{
cell.CellValue = new CellValue(value.ToString());
cell.DataType = GetCellType(value);
}
cell.CellReference = GetCellLocation();
IncreaseCellColumn();
return cell;
}
private CellValues GetCellType(object value)
{
CellValues type = CellValues.String;
if (value.GetType() == typeof(DateTime) || value.GetType() == typeof(DateTime?))
type = CellValues.Date;
if (value.GetType() == typeof(bool) || value.GetType() == typeof(bool?))
type = CellValues.Boolean;
if (IsNumericType(value.GetType()))
type = CellValues.Number;
return type;
}
public bool IsNumericType(Type type)
{
TypeCode typeCode = Type.GetTypeCode(type);
//The TypeCode of numerical types are between SByte (5) and Decimal (15).
return (int)typeCode >= 5 && (int)typeCode <= 15;
}
private void IncreaseCellColumn()
{
if (_cellColumnN1 < 90)
_cellColumnN1++;
else
{
_cellColumnN1 = 65;
if (!_cellColumnN2.HasValue)
_cellColumnN2 = 65;
else
_cellColumnN2++;
}
}
private void IncreaseRow()
{
_cellRow++;
_cellColumnN1 = 65;
_cellColumnN2 = null;
}
private string GetCellLocation()
{
Char? c1 = null;
if (_cellColumnN2.HasValue)
c1 = (char)_cellColumnN2;
Char c2 = (char)_cellColumnN1;
return string.Format("{0}{1}{2}", c1, c2, _cellRow);
}
#endregion
#region IDisposable
public override void Dispose()
{
if (_package != null)
{
_package.WorkbookPart.Workbook.Save();
_package.Close();
}
}
#endregion
}
Когда я создать файл Excel с помощью этого класса, появляется сообщение об ошибке: «Мы нашли ошибку в содержании ... " Excel исправляет файл и становится доступным. Почему у меня эта ошибка в Excel?
я смотрел немного в XML-файл sheet.xml, содержащийся в файле XLSX, есть несколько отличий:
генерируемый файл:
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheetData>
<x:row>
<x:c r="A1" t="str">
<x:v>a string</x:v>
</x:c>
<x:c r="B1" t="str">
<x:v>another string</x:v>
</x:c>
</x:row>
...
</x:sheetData>
</x:worksheet>
Капремонт файл:
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<dimension ref="A1:S12"/>
<sheetViews>
<sheetView tabSelected="1" workbookViewId="0">
<selection activeCell="I11" sqref="I11"/>
</sheetView>
</sheetViews>
<sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0.25"/>
<sheetData>
<row r="1" spans="1:19" x14ac:dyDescent="0.25">
<c r="A1" t="s">
<v>0</v>
</c>
<c r="B1" t="s">
<v>1</v>
</c>
<c r="C1" t="s">
<v>2</v>
</c>
</row>
...
</sheetData>
<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>
Я попытался изменить пространства имен, но это не сработало. Я знаю, что общие строки используются во втором xml, но я не думаю, что это проблема. ^^ Меня не интересует стиль, как маржа страницы, шрифт, ... (может быть полезно настроить ширину для столбцов ^^)
Я просто хочу хорошо сформированный файл xlsx.
У меня есть ошибка или упущение в моем коде?
Извините за мой английский, кстати «^^
Спасибо.