Готов первый компонент с картинкой, переделал на Interop

This commit is contained in:
Никита Потапов 2024-10-07 12:52:54 +04:00
parent 3c960c8ccb
commit bc43cb1957
3 changed files with 90 additions and 145 deletions

View File

@ -1,18 +1,6 @@
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using Excel = Microsoft.Office.Interop.Excel;
using System.ComponentModel;
using Fonts = DocumentFormat.OpenXml.Spreadsheet.Fonts;
using Font = DocumentFormat.OpenXml.Spreadsheet.Font;
using Color = DocumentFormat.OpenXml.Spreadsheet.Color;
using Fill = DocumentFormat.OpenXml.Spreadsheet.Fill;
using PatternFill = DocumentFormat.OpenXml.Spreadsheet.PatternFill;
using LeftBorder = DocumentFormat.OpenXml.Spreadsheet.LeftBorder;
using RightBorder = DocumentFormat.OpenXml.Spreadsheet.RightBorder;
using TopBorder = DocumentFormat.OpenXml.Spreadsheet.TopBorder;
using BottomBorder = DocumentFormat.OpenXml.Spreadsheet.BottomBorder;
namespace Components
{
@ -28,149 +16,93 @@ namespace Components
container.Add(this);
}
private void CheckInputValues(string filePath, string tableTitle, string[] imagePaths)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (string.IsNullOrEmpty(tableTitle))
{
throw new ArgumentNullException(nameof(tableTitle));
}
if (imagePaths == null)
{
throw new ArgumentNullException(nameof(imagePaths));
}
foreach (string imagePath in imagePaths)
{
if (string.IsNullOrEmpty(imagePath))
{
throw new ArgumentNullException("Image path is null");
}
}
}
public void CreateExcelWithImages(string filePath, string tableTitle, string[] imagePaths)
{
// Создаем новый Excel документ
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
{
// Добавляем WorkbookPart
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
CheckInputValues(filePath, tableTitle, imagePaths);
// Добавляем лист
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = workbook.Sheets[1];
// Добавляем таблицу стилей
WorkbookStylesPart stylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = CreateStylesheet();
stylesPart.Stylesheet.Save();
worksheet.Cells[1, 1] = tableTitle;
// Добавляем информацию о листе
Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet()
{
Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
InsertImagesInSingleCell(worksheet, imagePaths, 2, 1);
// Получаем данные листа
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
workbook.SaveAs(filePath);
workbook.Close();
excelApp.Quit();
// Создаем строку с заголовком
Row titleRow = new Row();
Cell titleCell = CreateTextCell(1, 1, tableTitle);
titleRow.Append(titleCell);
sheetData.Append(titleRow);
// Вставляем изображения в таблицу
for (int i = 0; i < imagePaths.Length; i++)
{
Row imageRow = new Row() { RowIndex = (uint)(i + 2) }; // Начинаем со 2-й строки, т.к. первая - заголовок
sheetData.Append(imageRow);
InsertImage(document, worksheetPart, imagePaths[i], (uint)(i + 2));
ReleaseObject(worksheet);
ReleaseObject(workbook);
ReleaseObject(excelApp);
}
workbookPart.Workbook.Save();
}
}
private void InsertImagesInSingleCell(Excel.Worksheet worksheet, string[] imagePaths, int rowIndex, int columnIndex)
{
Excel.Range cell = worksheet.Cells[rowIndex, columnIndex];
double currentTopOffset = 0;
// Метод для создания стилей
private Stylesheet CreateStylesheet()
foreach (string imagePath in imagePaths)
{
return new Stylesheet(
new Fonts(new Font(new FontSize() { Val = 11 }, new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }, new FontName() { Val = "Calibri" })),
new Fills(new Fill(new PatternFill() { PatternType = PatternValues.None })),
new Borders(new Border(new LeftBorder(), new RightBorder(), new TopBorder(), new BottomBorder(), new DiagonalBorder())),
new CellFormats(new CellFormat() { FontId = 0, FillId = 0, BorderId = 0, ApplyFont = true })
);
}
if (File.Exists(imagePath))
{
Excel.Pictures pictures = (Excel.Pictures)worksheet.Pictures(System.Reflection.Missing.Value);
Excel.Picture picture = pictures.Insert(imagePath);
// Метод для создания текстовой ячейки
private Cell CreateTextCell(int columnIndex, int rowIndex, string text)
{
Cell cell = new Cell()
{
DataType = CellValues.String,
CellReference = GetCellReference(columnIndex, rowIndex)
};
cell.CellValue = new CellValue(text);
return cell;
}
picture.Left = cell.Left;
picture.Top = cell.Top + currentTopOffset;
// Метод для получения ссылки на ячейку (например, A1)
private string GetCellReference(int columnIndex, int rowIndex)
{
char columnLetter = (char)('A' + columnIndex - 1);
return $"{columnLetter}{rowIndex}";
}
// Метод для вставки изображения в ячейку
private void InsertImage(SpreadsheetDocument document, WorksheetPart worksheetPart, string imagePath, uint rowIndex)
{
DrawingsPart drawingsPart;
ImagePart imagePart;
WorksheetDrawing worksheetDrawing;
// Проверяем, существует ли уже часть с чертежами (DrawingsPart)
if (worksheetPart.DrawingsPart == null)
{
drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
worksheetDrawing = new WorksheetDrawing();
drawingsPart.WorksheetDrawing = worksheetDrawing;
currentTopOffset += picture.Height;
}
else
{
drawingsPart = worksheetPart.DrawingsPart;
worksheetDrawing = drawingsPart.WorksheetDrawing;
throw new FileNotFoundException("Image not found at: " + imagePath);
}
}
}
// Добавляем изображение в DrawingsPart
if (imagePath.EndsWith(".png"))
private void ReleaseObject(object obj)
{
imagePart = drawingsPart.AddImagePart(ImagePartType.Png);
}
else if (imagePath.EndsWith(".jpg") || imagePath.EndsWith(".jpeg"))
try
{
imagePart = drawingsPart.AddImagePart(ImagePartType.Jp2);
}
else
if (obj != null)
{
imagePart = drawingsPart.AddImagePart(ImagePartType.Jpeg);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
using (FileStream stream = new FileStream(imagePath, FileMode.Open))
}
catch (Exception ex)
{
imagePart.FeedData(stream);
obj = null;
Console.WriteLine("Error with cleanup COM object: " + ex.ToString());
}
finally
{
GC.Collect();
}
var imageId = drawingsPart.GetIdOfPart(imagePart);
// Размеры изображения
var extents = new Extents() { Cx = 990000L, Cy = 792000L }; // Пример размеров
// Якорь для изображения
var twoCellAnchor = new TwoCellAnchor(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(new ColumnId("0"), new ColumnOffset("0"), new RowId((rowIndex - 1).ToString()), new RowOffset("0")),
new DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(new ColumnId("1"), new ColumnOffset("0"), new RowId(rowIndex.ToString()), new RowOffset("0")),
new DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualPictureProperties(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualDrawingProperties() { Id = (UInt32Value)1U, Name = "Picture 1" },
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualPictureDrawingProperties()),
new DocumentFormat.OpenXml.Drawing.Spreadsheet.BlipFill(
new DocumentFormat.OpenXml.Drawing.Blip() { Embed = imageId },
new DocumentFormat.OpenXml.Drawing.Stretch(new DocumentFormat.OpenXml.Drawing.FillRectangle())),
new DocumentFormat.OpenXml.Drawing.Spreadsheet.ShapeProperties(
new DocumentFormat.OpenXml.Drawing.Transform2D(new DocumentFormat.OpenXml.Drawing.Offset() { X = 0, Y = 0 }, extents),
new DocumentFormat.OpenXml.Drawing.PresetGeometry(new DocumentFormat.OpenXml.Drawing.AdjustValueList()) { Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle })
),
new ClientData()
);
worksheetDrawing.Append(twoCellAnchor);
worksheetPart.Worksheet.Save();
}
}
}

View File

@ -7,8 +7,21 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<COMReference Include="Microsoft.Office.Interop.Excel">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>9</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>00020813-0000-0000-c000-000000000046</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.1.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
</ItemGroup>
</Project>

View File

@ -17,11 +17,11 @@
try
{
componentExcelWithImage.CreateExcelWithImages(textBoxFilePath.Text, textBoxTitle.Text, list);
MessageBox.Show("Успех");
MessageBox.Show("Файл успешно создан", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception)
catch (Exception ex)
{
MessageBox.Show("Ошибка");
MessageBox.Show($"Ошибка при создании файла:\n{ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@ -59,7 +59,7 @@
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "d:\\tmp";
openFileDialog.Filter = "All files (*.*)|*.*";
openFileDialog.Filter = "Image files (*.jpeg;*.jpg;*.png)|*.jpeg;*.jpg;*.png|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;