OnlineSalesAutoCrop/Api/OnlineSalesAutoCrop.CoreAPI.Models/Global/ExcelTools.cs
2026-06-14 12:46:29 +06:00

111 lines
4.0 KiB
C#

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using A = DocumentFormat.OpenXml.Drawing;
using Xdr = DocumentFormat.OpenXml.Drawing.Spreadsheet;
namespace OnlineSalesAutoCrop.CoreAPI.Models.Global
{
internal static class ExcelTools
{
private static PartTypeInfo GetImagePartTypeByBitmap(byte[] bytes)
{
byte[] tiff = "II*"u8.ToArray(); // TIFF
byte[] tiff2 = "MM*"u8.ToArray(); // TIFF
byte[] jpeg = [255, 216, 255]; // jpeg
byte[] bmp = Encoding.ASCII.GetBytes("BM"); // BMP
byte[] gif = Encoding.ASCII.GetBytes("GIF"); // GIF
byte[] png = [137, 80, 78, 71]; // PNG
if (bmp.SequenceEqual(bytes.Take(bmp.Length)))
return ImagePartType.Bmp;
else if (gif.SequenceEqual(bytes.Take(gif.Length)))
return ImagePartType.Gif;
else if (png.SequenceEqual(bytes.Take(png.Length)))
return ImagePartType.Png;
else if (tiff.SequenceEqual(bytes.Take(tiff.Length)))
return ImagePartType.Tiff;
else if (tiff2.SequenceEqual(bytes.Take(tiff2.Length)))
return ImagePartType.Tiff;
else if (jpeg.SequenceEqual(bytes.Take(jpeg.Length)))
return ImagePartType.Jpeg;
throw new InvalidOperationException("Image type could not be determined.");
}
/// <summary>
///
/// </summary>
/// <param name="worksheetPart"></param>
/// <param name="stream"></param>
/// <param name="imgDescription"></param>
/// <param name="colNumber"></param>
/// <param name="rowNumber"></param>
public static void AddImage(WorksheetPart worksheetPart, Stream stream, string imgDescription, int colNumber, int rowNumber)
{
var drawingsPart = worksheetPart.DrawingsPart;
drawingsPart ??= worksheetPart.AddNewPart<DrawingsPart>();
if (!worksheetPart.Worksheet.ChildElements.OfType<Drawing>().Any())
worksheetPart.Worksheet.AppendChild(new Drawing { Id = worksheetPart.GetIdOfPart(drawingsPart) });
drawingsPart.WorksheetDrawing ??= new Xdr.WorksheetDrawing();
var worksheetDrawing = drawingsPart.WorksheetDrawing;
ImagePart imagePart;
long extentsCx = 0, extentsCy = 0;
using (MemoryStream ms = new())
{
stream.Position = 0;
stream.CopyTo(ms);
stream.Position = 0;
#pragma warning disable CA1416 // Validate platform compatibility
using Bitmap bmp = new(ms);
imagePart = drawingsPart.AddImagePart(GetImagePartTypeByBitmap(ms.ToArray()));
imagePart.FeedData(stream);
extentsCx = bmp.Width * (long)(914400 / bmp.HorizontalResolution);
extentsCy = bmp.Height * (long)(914400 / bmp.VerticalResolution);
#pragma warning restore CA1416 // Validate platform compatibility
}
uint nvpId = worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>().Any() ? (UInt32Value)worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>().Max(p => p.Id.Value) + 1 : 1U;
Xdr.OneCellAnchor oneCellAnchor = new(
new Xdr.FromMarker
{
ColumnId = new Xdr.ColumnId((colNumber - 1).ToString()),
RowId = new Xdr.RowId((rowNumber - 1).ToString()),
ColumnOffset = new Xdr.ColumnOffset("0"),
RowOffset = new Xdr.RowOffset("0")
},
new Xdr.Extent { Cx = extentsCx, Cy = extentsCy },
new Xdr.Picture(
new Xdr.NonVisualPictureProperties(
new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = "Picture " + nvpId, Description = imgDescription },
new Xdr.NonVisualPictureDrawingProperties(new A.PictureLocks { NoChangeAspect = true })
),
new Xdr.BlipFill(
new A.Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print },
new A.Stretch(new A.FillRectangle())
),
new Xdr.ShapeProperties(
new A.Transform2D(
new A.Offset { X = 0, Y = 0 },
new A.Extents { Cx = extentsCx, Cy = extentsCy }
),
new A.PresetGeometry { Preset = A.ShapeTypeValues.Rectangle }
)
),
new Xdr.ClientData()
);
worksheetDrawing.Append(oneCellAnchor);
}
}
}