浏览代码

优化excel导出

懒得勤快 3 年之前
父节点
当前提交
ec0e5042a2
共有 3 个文件被更改,包括 1106 次插入244 次删除
  1. 201 242
      Masuit.Tools.Excel/ExcelExtension.cs
  2. 904 0
      Masuit.Tools.Excel/ImageDetector.cs
  3. 1 2
      Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

+ 201 - 242
Masuit.Tools.Excel/ExcelExtension.cs

@@ -1,304 +1,263 @@
 using OfficeOpenXml;
 using OfficeOpenXml.Drawing;
-using SixLabors.ImageSharp;
 using System;
 using System.Collections.Generic;
 using System.Data;
-using System.Drawing;
-using System.Drawing.Imaging;
 using System.IO;
 using System.Linq;
 using System.Text;
-using Image = SixLabors.ImageSharp.Image;
+using OfficeOpenXml.Style;
 
-namespace Masuit.Tools.Excel
+namespace Masuit.Tools.Excel;
+
+public static class ExcelExtension
 {
-    public static class ExcelExtension
+    static ExcelExtension()
+    {
+        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
+    }
+
+    /// <summary>
+    /// 将内存表自动填充到Excel
+    /// </summary>
+    /// <param name="sheetTables">sheet名和内存表的映射</param>
+    /// <param name="password">密码</param>
+    /// <param name="settings">列设置</param>
+    /// <returns>内存流</returns>
+    public static MemoryStream ToExcel(this Dictionary<string, DataTable> sheetTables, string password = null, ColumnSettings settings = null)
     {
-        static ExcelExtension()
+        using var pkg = new ExcelPackage();
+        foreach (var pair in sheetTables)
         {
-            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
+            pair.Value.TableName = pair.Key;
+            CreateWorksheet(pkg, pair.Value, settings);
         }
 
-        /// <summary>
-        /// 将内存表自动填充到Excel
-        /// </summary>
-        /// <param name="sheetTables">sheet名和内存表的映射</param>
-        /// <param name="password">密码</param>
-        /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this Dictionary<string, DataTable> sheetTables, string password = null, ColumnSettings settings = null)
-        {
-            using var pkg = new ExcelPackage();
-            foreach (var pair in sheetTables)
-            {
-                pair.Value.TableName = pair.Key;
-                CreateWorksheet(pkg, pair.Value, settings);
-            }
+        return SaveAsStream(pkg, password);
+    }
 
-            return SaveAsStream(pkg, password);
+    /// <summary>
+    /// 将内存表自动填充到Excel
+    /// </summary>
+    /// <param name="tables">内存表</param>
+    /// <param name="password">密码</param>
+    /// <returns>内存流</returns>
+    public static MemoryStream ToExcel(this List<DataTable> tables, string password = null, ColumnSettings settings = null)
+    {
+        using var pkg = new ExcelPackage();
+        foreach (var table in tables)
+        {
+            CreateWorksheet(pkg, table, settings);
         }
 
-        /// <summary>
-        /// 将内存表自动填充到Excel
-        /// </summary>
-        /// <param name="tables">内存表</param>
-        /// <param name="password">密码</param>
-        /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this List<DataTable> tables, string password = null, ColumnSettings settings = null)
-        {
-            using var pkg = new ExcelPackage();
-            foreach (var table in tables)
-            {
-                CreateWorksheet(pkg, table, settings);
-            }
+        return SaveAsStream(pkg, password);
+    }
 
-            return SaveAsStream(pkg, password);
-        }
+    /// <summary>
+    /// 将内存表自动填充到Excel
+    /// </summary>
+    /// <param name="table">内存表</param>
+    /// <param name="password">密码</param>
+    /// <returns>内存流</returns>
+    public static MemoryStream ToExcel(this DataTable table, string password = null, ColumnSettings settings = null)
+    {
+        using var pkg = new ExcelPackage();
+        CreateWorksheet(pkg, table, settings);
+        return SaveAsStream(pkg, password);
+    }
 
-        /// <summary>
-        /// 将内存表自动填充到Excel
-        /// </summary>
-        /// <param name="table">内存表</param>
-        /// <param name="password">密码</param>
-        /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this DataTable table, string password = null, ColumnSettings settings = null)
+    private static MemoryStream SaveAsStream(ExcelPackage pkg, string password)
+    {
+        var ms = new MemoryStream();
+        if (!string.IsNullOrEmpty(password))
         {
-            using var pkg = new ExcelPackage();
-            CreateWorksheet(pkg, table, settings);
-            return SaveAsStream(pkg, password);
+            pkg.SaveAs(ms, password);
         }
-
-        private static MemoryStream SaveAsStream(ExcelPackage pkg, string password)
+        else
         {
-            var ms = new MemoryStream();
-            if (!string.IsNullOrEmpty(password))
-            {
-                pkg.SaveAs(ms, password);
-            }
-            else
-            {
-                pkg.SaveAs(ms);
-            }
-
-            return ms;
+            pkg.SaveAs(ms);
         }
 
-        public static void CreateWorksheet(this ExcelPackage pkg, DataTable table, ColumnSettings settings = null)
+        return ms;
+    }
+
+    public static void CreateWorksheet(this ExcelPackage pkg, DataTable table, ColumnSettings settings = null)
+    {
+        if (string.IsNullOrEmpty(table.TableName))
         {
-            if (string.IsNullOrEmpty(table.TableName))
-            {
-                table.TableName = "Sheet1";
-            }
+            table.TableName = "Sheet1";
+        }
 
-            pkg.Workbook.Worksheets.Add(table.TableName);
-            var sheet = pkg.Workbook.Worksheets[table.TableName];
+        pkg.Workbook.Worksheets.Add(table.TableName);
+        var sheet = pkg.Workbook.Worksheets[table.TableName];
 
-            FillWorksheet(sheet, table, settings);
+        FillWorksheet(sheet, table, settings);
 
-            //打印方向:纵向
-            sheet.PrinterSettings.Orientation = eOrientation.Landscape;
+        sheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
 
-            //集中在一页里打印
-            sheet.PrinterSettings.FitToPage = true;
+        //打印方向:纵向
+        sheet.PrinterSettings.Orientation = eOrientation.Landscape;
 
-            //使用A4纸
-            sheet.PrinterSettings.PaperSize = ePaperSize.A4;
-        }
+        //集中在一页里打印
+        sheet.PrinterSettings.FitToPage = true;
+
+        //使用A4纸
+        sheet.PrinterSettings.PaperSize = ePaperSize.A4;
+    }
 
-        /// <summary>
-        /// 从datatable填充工作簿
-        /// </summary>
-        /// <param name="sheet">工作簿</param>
-        /// <param name="table">数据</param>
-        /// <param name="settings">列设置</param>
-        /// <param name="startRow">起始行,默认第一行</param>
-        /// <param name="startColumn">起始列,默认第一列A列</param>
-        public static void FillWorksheet(this ExcelWorksheet sheet, DataTable table, ColumnSettings settings = null, int startRow = 1, int startColumn = 1)
+    /// <summary>
+    /// 从datatable填充工作簿
+    /// </summary>
+    /// <param name="sheet">工作簿</param>
+    /// <param name="table">数据</param>
+    /// <param name="settings">列设置</param>
+    /// <param name="startRow">起始行,默认第一行</param>
+    /// <param name="startColumn">起始列,默认第一列A列</param>
+    public static void FillWorksheet(this ExcelWorksheet sheet, DataTable table, ColumnSettings settings = null, int startRow = 1, int startColumn = 1)
+    {
+        // 填充表头
+        var maxWidth = new int[table.Columns.Count];
+        for (var j = 0; j < table.Columns.Count; j++)
         {
-            // 填充表头
-            var maxWidth = new int[table.Columns.Count];
-            for (var j = 0; j < table.Columns.Count; j++)
-            {
-                sheet.SetValue(startRow, j + startColumn, table.Columns[j].ColumnName);
-                maxWidth[j] = Encoding.UTF8.GetBytes(table.Columns[j].ColumnName).Length;
-            }
+            sheet.SetValue(startRow, j + startColumn, table.Columns[j].ColumnName);
+            maxWidth[j] = Encoding.UTF8.GetBytes(table.Columns[j].ColumnName).Length;
+        }
 
-            sheet.Row(startRow).Style.Font.Bold = true; // 表头设置为粗体
-            sheet.Row(startRow).Style.Font.Size = sheet.Row(startRow).Style.Font.Size * 1.11f; // 表头字号放大1.11倍
-            sheet.Row(startRow).CustomHeight = true; // 自动调整行高
-            sheet.Cells.AutoFitColumns(); // 表头自适应列宽
-            sheet.Cells.Style.WrapText = true;
-            if (settings != null)
+        sheet.Row(startRow).Style.Font.Bold = true; // 表头设置为粗体
+        sheet.Row(startRow).Style.Font.Size = sheet.Row(startRow).Style.Font.Size * 1.11f; // 表头字号放大1.11倍
+        sheet.Row(startRow).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
+        sheet.Row(startRow).CustomHeight = true; // 自动调整行高
+        sheet.Cells.AutoFitColumns(); // 表头自适应列宽
+        sheet.Cells.Style.WrapText = true;
+        if (settings != null)
+        {
+            foreach (var x in settings.ColumnTypes)
             {
-                foreach (var x in settings.ColumnTypes)
-                {
-                    sheet.Column(x.Key).Style.Numberformat.Format = x.Value;
-                }
+                sheet.Column(x.Key).Style.Numberformat.Format = x.Value;
             }
+        }
 
-            // 填充内容
-            for (var i = 0; i < table.Rows.Count; i++)
+        // 填充内容
+        for (var i = 0; i < table.Rows.Count; i++)
+        {
+            sheet.Row(i + startRow + 1).CustomHeight = true; // 自动调整行高
+            for (var j = 0; j < table.Columns.Count; j++)
             {
-                sheet.Row(i + startRow + 1).CustomHeight = true; // 自动调整行高
-                for (var j = 0; j < table.Columns.Count; j++)
+                switch (table.Rows[i][j])
                 {
-                    switch (table.Rows[i][j])
-                    {
-                        case Stream s:
+                    case Stream s:
+                        {
+                            if (s.Length > 2)
                             {
-                                if (s.Length > 2)
-                                {
-                                    var (pictureType, ms) = Detect(s);
-                                    var bmp = new ExcelImage(ms, pictureType).Bounds;
-                                    var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), ms, pictureType);
-                                    picture.SetPosition(i + startRow, 3, j + startColumn - 1, 5); //设置图片显示位置
-                                    var percent = Math.Min(11000f / bmp.Height, 100);
-                                    picture.SetSize((int)percent);
-                                    sheet.Row(i + startRow + 1).Height = 90;
-                                    sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, bmp.Width * percent / 600 > 32 ? bmp.Width * percent / 600 : 32);
-                                }
+                                var pictureType = ImageDetector.GetPictureType(s) ?? throw new ArgumentException($"{i}行{j}列图像格式不受支持");
+                                var bmp = new ExcelImage(s, pictureType).Bounds;
+                                var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), s, pictureType);
+                                picture.SetPosition(i + startRow, 3, j + startColumn - 1, 5); //设置图片显示位置
+                                var percent = Math.Round(Math.Min(12000f / bmp.Height, 100));
+                                picture.SetSize((int)percent);
+                                sheet.Row(i + startRow + 1).Height = 90;
+                                sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, bmp.Width * percent / 400);
+                            }
 
-                                sheet.SetValue(i + startRow + 1, j + startColumn, "");
+                            sheet.SetValue(i + startRow + 1, j + startColumn, "");
 
-                                break;
-                            }
+                            break;
+                        }
 
-                        case IEnumerable<Stream> streams:
+                    case IEnumerable<Stream> streams:
+                        {
+                            double sumWidth = 0;
+                            foreach (var stream in streams.Where(stream => stream.Length > 2))
                             {
-                                double sumWidth = 0;
-                                foreach (var stream in streams.Where(stream => stream.Length > 2))
-                                {
-                                    var (pictureType, ms) = Detect(stream);
-                                    var bmp = new ExcelImage(ms, pictureType).Bounds;
-                                    var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), ms, pictureType);
-                                    picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)(5 + sumWidth)); //设置图片显示位置
-                                    var percent = Math.Min(11000f / bmp.Height, 100);
-                                    picture.SetSize((int)percent);
-                                    sheet.Row(i + startRow + 1).Height = 90;
-                                    sumWidth += bmp.Width * 1.0 * percent / 100 + 5;
-                                    sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 6 > 32 ? sumWidth / 6 : 32);
-                                }
-
-                                sheet.SetValue(i + startRow + 1, j + startColumn, "");
-                                break;
+                                var pictureType = ImageDetector.GetPictureType(stream) ?? throw new ArgumentException($"{i}行{j}列图像格式不受支持");
+                                var bmp = new ExcelImage(stream, pictureType).Bounds;
+                                var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), stream, pictureType);
+                                picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)Math.Ceiling(5 + sumWidth)); //设置图片显示位置
+                                var percent = Math.Min(12000f / bmp.Height, 100);
+                                picture.SetSize((int)percent);
+                                sheet.Row(i + startRow + 1).Height = 90;
+                                sumWidth += bmp.Width * percent / 100 + 5;
+                                sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 5);
                             }
 
-                        case IDictionary<string, Stream> dic:
-                            {
-                                double sumWidth = 0;
-                                foreach (var kv in dic.Where(kv => kv.Value.Length > 2))
-                                {
-                                    var (pictureType, ms) = Detect(kv.Value);
-                                    var bmp = new ExcelImage(ms, pictureType).Bounds;
-                                    var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), ms, pictureType, new Uri(kv.Key));
-                                    picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)(5 + sumWidth)); //设置图片显示位置
-                                    var percent = Math.Min(11000f / bmp.Height, 100);
-                                    picture.SetSize((int)percent);
-                                    sheet.Row(i + startRow + 1).Height = 90;
-                                    sumWidth += bmp.Width * 1.0 * percent / 100 + 5;
-                                    sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 6 > 32 ? sumWidth / 6 : 32);
-                                }
+                            sheet.SetValue(i + startRow + 1, j + startColumn, "");
+                            break;
+                        }
 
-                                sheet.SetValue(i + startRow + 1, j + startColumn, "");
-                                break;
+                    case IDictionary<string, Stream> dic:
+                        {
+                            double sumWidth = 0;
+                            foreach (var kv in dic.Where(kv => kv.Value.Length > 2))
+                            {
+                                var pictureType = ImageDetector.GetPictureType(kv.Value) ?? throw new ArgumentException($"{i}行{j}列图像格式不受支持");
+                                var bmp = new ExcelImage(kv.Value, pictureType).Bounds;
+                                var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), kv.Value, pictureType, new Uri(kv.Key));
+                                picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)Math.Ceiling(5 + sumWidth)); //设置图片显示位置
+                                var percent = Math.Min(12000f / bmp.Height, 100);
+                                picture.SetSize((int)percent);
+                                sheet.Row(i + startRow + 1).Height = 90;
+                                sumWidth += bmp.Width * percent / 100 + 5;
+                                sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 5);
                             }
 
-                        case IDictionary<string, MemoryStream> dic:
-                            {
-                                double sumWidth = 0;
-                                foreach (var kv in dic.Where(kv => kv.Value.Length > 2))
-                                {
-                                    var (pictureType, ms) = Detect(kv.Value);
-                                    var bmp = new ExcelImage(ms, pictureType).Bounds;
-                                    var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), ms, pictureType, new Uri(kv.Key));
-                                    picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)(5 + sumWidth)); //设置图片显示位置
-                                    var percent = Math.Min(11000f / bmp.Height, 100);
-                                    picture.SetSize((int)percent);
-                                    sheet.Row(i + startRow + 1).Height = 90;
-                                    sumWidth += bmp.Width * 1.0 * percent / 100 + 5;
-                                    sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 6 > 32 ? sumWidth / 6 : 32);
-                                }
+                            sheet.SetValue(i + startRow + 1, j + startColumn, "");
+                            break;
+                        }
 
-                                sheet.SetValue(i + startRow + 1, j + startColumn, "");
-                                break;
+                    case IDictionary<string, MemoryStream> dic:
+                        {
+                            double sumWidth = 0;
+                            foreach (var kv in dic.Where(kv => kv.Value.Length > 2))
+                            {
+                                var pictureType = ImageDetector.GetPictureType(kv.Value) ?? throw new ArgumentException($"{i}行{j}列图像格式不受支持");
+                                var bmp = new ExcelImage(kv.Value, pictureType).Bounds;
+                                var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), kv.Value, pictureType, new Uri(kv.Key));
+                                picture.SetPosition(i + startRow, 3, j + startColumn - 1, (int)Math.Ceiling(5 + sumWidth)); //设置图片显示位置
+                                var percent = Math.Min(12000f / bmp.Height, 100);
+                                picture.SetSize((int)percent);
+                                sheet.Row(i + startRow + 1).Height = 90;
+                                sumWidth += bmp.Width * percent / 100 + 5;
+                                sheet.Column(j + startColumn).Width = Math.Max(sheet.Column(j + startColumn).Width, sumWidth / 5);
                             }
 
-                        default:
+                            sheet.SetValue(i + startRow + 1, j + startColumn, "");
+                            break;
+                        }
+
+                    default:
+                        {
+                            sheet.SetValue(i + startRow + 1, j + startColumn, table.Rows[i][j] ?? "");
+                            if (table.Rows[i][j] is ValueType)
                             {
-                                sheet.SetValue(i + startRow + 1, j + startColumn, table.Rows[i][j] ?? "");
-                                if (table.Rows[i][j] is ValueType)
-                                {
-                                    sheet.Column(j + startColumn).AutoFit();
-                                }
-                                else
+                                sheet.Column(j + startColumn).AutoFit();
+                            }
+                            else
+                            {
+                                // 根据单元格内容长度来自适应调整列宽
+                                sheet.Column(j + startColumn).Width = Math.Max(Encoding.UTF8.GetBytes(table.Rows[i][j].ToString() ?? string.Empty).Length + 2, sheet.Column(j + startColumn).Width);
+                                if (sheet.Column(j + startColumn).Width > 110)
                                 {
-                                    // 根据单元格内容长度来自适应调整列宽
-                                    sheet.Column(j + startColumn).Width = Math.Max(Encoding.UTF8.GetBytes(table.Rows[i][j].ToString() ?? string.Empty).Length + 2, sheet.Column(j + startColumn).Width);
-                                    if (sheet.Column(j + startColumn).Width > 110)
-                                    {
-                                        sheet.Column(j + startColumn).AutoFit(100, 110);
-                                    }
+                                    sheet.Column(j + startColumn).AutoFit(100, 110);
                                 }
-
-                                break;
                             }
-                    }
-                }
-            }
-        }
-
-        private static readonly NumberFormater NumberFormater = new("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1);
 
-        /// <summary>
-        /// 检测图片格式
-        /// </summary>
-        /// <param name="stream"></param>
-        /// <returns></returns>
-        private static (ePictureType type, Stream stream) Detect(Stream stream)
-        {
-            try
-            {
-                var pictureType = Image.DetectFormat(stream).Name switch
-                {
-                    "JPEG" => ePictureType.Jpg,
-                    "PNG" => ePictureType.Png,
-                    "GIF" => ePictureType.Gif,
-                    "BMP" => ePictureType.Bmp,
-                    "SVG" => ePictureType.Svg,
-                    "TIF" => ePictureType.Tif,
-                    "WEBP" => ePictureType.WebP,
-                    _ => default
-                };
-                return (pictureType, stream);
-            }
-            catch
-            {
-                try
-                {
-                    using var image = Image.Load(stream);
-                    var ms = new MemoryStream();
-                    image.SaveAsWebp(ms);
-                    return (ePictureType.WebP, ms);
-                }
-                catch
-                {
-                    using var bmp = new Bitmap(stream);
-                    var ms = new MemoryStream();
-                    bmp.Save(ms, ImageFormat.Jpeg);
-                    return (ePictureType.Jpg, ms);
+                            break;
+                        }
                 }
             }
         }
+    }
 
-        /// <summary>
-        /// 获取字母列
-        /// </summary>
-        /// <param name="sheet"></param>
-        /// <param name="index"></param>
-        /// <returns></returns>
-        public static ExcelColumn Column(this ExcelWorksheet sheet, string index)
-        {
-            return sheet.Column((int)NumberFormater.FromString(index));
-        }
+    private static readonly NumberFormater NumberFormater = new("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1);
+
+    /// <summary>
+    /// 获取字母列
+    /// </summary>
+    /// <param name="sheet"></param>
+    /// <param name="index"></param>
+    /// <returns></returns>
+    public static ExcelColumn Column(this ExcelWorksheet sheet, string index)
+    {
+        return sheet.Column((int)NumberFormater.FromString(index));
     }
 }

+ 904 - 0
Masuit.Tools.Excel/ImageDetector.cs

@@ -0,0 +1,904 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using OfficeOpenXml.Drawing;
+using OfficeOpenXml.Packaging.Ionic.Zlib;
+
+namespace Masuit.Tools.Excel;
+
+public static class ImageDetector
+{
+    private const float MToInch = 39.3700787F;
+    private const float CmToInch = MToInch * 0.01F;
+    public const float MmToInch = CmToInch * 0.1F;
+    private const float HundredthThMmToInch = MmToInch * 0.01F;
+    internal const float StandardDPI = 96f;
+
+    internal struct TifIfd
+    {
+        public short Tag;
+        public short Type;
+        public int Count;
+        public int ValueOffset;
+    }
+
+    /// <summary>
+    /// 获取图像格式
+    /// </summary>
+    /// <param name="ms"></param>
+    /// <returns></returns>
+    public static ePictureType? GetPictureType(Stream ms)
+    {
+        var br = new BinaryReader(ms);
+        if (IsJpg(br))
+        {
+            return ePictureType.Jpg;
+        }
+        if (IsBmp(br, out _))
+        {
+            return ePictureType.Bmp;
+        }
+        else if (IsGif(br))
+        {
+            return ePictureType.Gif;
+        }
+        else if (IsPng(br))
+        {
+            return ePictureType.Png;
+        }
+        else if (IsTif(br, out _))
+        {
+            return ePictureType.Tif;
+        }
+        else if (IsIco(br))
+        {
+            return ePictureType.Ico;
+        }
+        else if (IsWebP(br))
+        {
+            return ePictureType.WebP;
+        }
+        else if (IsEmf(br))
+        {
+            return ePictureType.Emf;
+        }
+        else if (IsWmf(br))
+        {
+            return ePictureType.Wmf;
+        }
+        else if (IsSvg(ms))
+        {
+            return ePictureType.Svg;
+        }
+        else if (IsGZip(br))
+        {
+            _ = ExtractImage(ToArray(ms), out ePictureType? pt);
+            return pt;
+        }
+        return null;
+    }
+
+    /// <summary>
+    ///
+    /// </summary>
+    /// <param name="stream"></param>
+    /// <returns></returns>
+    public static byte[] ToArray(Stream stream)
+    {
+        stream.Position = 0;
+        byte[] bytes = new byte[stream.Length];
+        stream.Read(bytes, 0, bytes.Length);
+
+        // 设置当前流的位置为流的开始
+        stream.Seek(0, SeekOrigin.Begin);
+        return bytes;
+    }
+
+    private static bool IsGZip(BinaryReader br)
+    {
+        br.BaseStream.Position = 0;
+        var sign = br.ReadBytes(2);
+        return IsGZip(sign);
+    }
+
+    private static bool IsGZip(byte[] sign)
+    {
+        return sign.Length >= 2 && sign[0] == 0x1F && sign[1] == 0x8B;
+    }
+
+    internal static bool TryGetImageBounds(ePictureType pictureType, MemoryStream ms, ref double width, ref double height, out double horizontalResolution, out double verticalResolution)
+    {
+        width = 0;
+        height = 0;
+        horizontalResolution = verticalResolution = StandardDPI;
+        try
+        {
+            ms.Seek(0, SeekOrigin.Begin);
+            if (pictureType == ePictureType.Bmp && IsBmp(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            if (pictureType == ePictureType.Jpg && IsJpg(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            if (pictureType == ePictureType.Gif && IsGif(ms, ref width, ref height))
+            {
+                return true;
+            }
+            if (pictureType == ePictureType.Png && IsPng(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            if (pictureType == ePictureType.Emf && IsEmf(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            if (pictureType == ePictureType.Wmf && IsWmf(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            else if (pictureType == ePictureType.Svg && IsSvg(ms, ref width, ref height))
+            {
+                return true;
+            }
+            else if (pictureType == ePictureType.Tif && IsTif(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            else if (pictureType == ePictureType.WebP && IsWebP(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
+            {
+                return true;
+            }
+            else if (pictureType == ePictureType.Ico && IsIcon(ms, ref width, ref height))
+            {
+                return true;
+            }
+            return false;
+        }
+        catch
+        {
+            return false;
+        }
+    }
+
+    internal static byte[] ExtractImage(byte[] img, out ePictureType? type)
+    {
+        if (IsGZip(img))
+        {
+            try
+            {
+                var ms = new MemoryStream(img);
+                var msOut = new MemoryStream();
+                const int bufferSize = 4096;
+                var buffer = new byte[bufferSize];
+                using (var z = new GZipStream(ms, CompressionMode.Decompress))
+                {
+                    int size = 0;
+                    do
+                    {
+                        size = z.Read(buffer, 0, bufferSize);
+                        if (size > 0)
+                        {
+                            msOut.Write(buffer, 0, size);
+                        }
+                    }
+                    while (size == bufferSize);
+                    msOut.Position = 0;
+                    var br = new BinaryReader(msOut);
+                    if (IsEmf(br))
+                    {
+                        type = ePictureType.Emf;
+                    }
+                    else if (IsWmf(br))
+                    {
+                        type = ePictureType.Wmf;
+                    }
+                    else
+                    {
+                        type = null;
+                    }
+                    msOut.Position = 0;
+                    return msOut.ToArray();
+                }
+            }
+            catch
+            {
+                type = null;
+                return img;
+            }
+        }
+        type = null;
+        return img;
+    }
+
+    private static bool IsJpg(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsJpg(br))
+            {
+                float xDensity = 1, yDensity = 1;
+                while (ms.Position < ms.Length)
+                {
+                    var id = GetUInt16BigEndian(br);
+                    var length = (int)GetInt16BigEndian(br);
+                    switch (id)
+                    {
+                        case 0xFFE0:
+                            var identifier = br.ReadBytes(5); //JFIF\0
+                            var version = br.ReadBytes(2);
+                            var unit = br.ReadByte();
+                            xDensity = (int)GetInt16BigEndian(br);
+                            yDensity = (int)GetInt16BigEndian(br);
+
+                            if (unit == 1)
+                            {
+                                horizontalResolution = xDensity;
+                                verticalResolution = yDensity;
+                            }
+                            else if (unit == 2)
+                            {
+                                horizontalResolution = xDensity * CmToInch;
+                                verticalResolution = yDensity * CmToInch;
+                            }
+
+                            ms.Position += length - 14;
+                            break;
+
+                        case 0xFFE1:
+                            var pos = ms.Position;
+                            identifier = br.ReadBytes(6); //EXIF\0\0 or //EXIF\FF\FF
+                            double w = 0, h = 0;
+                            ReadTiffHeader(br, ref w, ref h, ref horizontalResolution, ref verticalResolution);
+                            ms.Position = pos + length - 2;
+                            break;
+
+                        case 0xFFC0:
+                        case 0xFFC1:
+                        case 0xFFC2:
+                            var precision = br.ReadByte(); //Bits
+                            height = GetUInt16BigEndian(br);
+                            width = GetUInt16BigEndian(br);
+                            br.Close();
+                            return true;
+
+                        case 0xFFD9:
+                            return height != 0 && width != 0;
+
+                        default:
+                            ms.Position += length - 2;
+                            break;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    private static bool IsJpg(BinaryReader br)
+    {
+        br.BaseStream.Position = 0;
+        var sign = br.ReadBytes(2);    //FF D8
+        return sign.Length >= 2 && sign[0] == 0xFF && sign[1] == 0xD8;
+    }
+
+    private static bool IsGif(MemoryStream ms, ref double width, ref double height)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsGif(br))
+            {
+                width = br.ReadUInt16();
+                height = br.ReadUInt16();
+                br.Close();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static bool IsGif(BinaryReader br)
+    {
+        br.BaseStream.Seek(0, SeekOrigin.Begin);
+        var b = br.ReadBytes(6);
+        return b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46;    //byte 4-6 contains the version, but we don't check them here.
+    }
+
+    private static bool IsBmp(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsBmp(br, out string sign))
+            {
+                var size = br.ReadInt32();
+                var reserved = br.ReadBytes(4);
+                var offsetData = br.ReadInt32();
+
+                //Info Header
+                var ihSize = br.ReadInt32(); //Should be 40
+                width = br.ReadInt32();
+                height = br.ReadInt32();
+
+                if (sign == "BM")
+                {
+                    br.ReadBytes(12);
+                    horizontalResolution = br.ReadInt32() / MToInch;
+                    verticalResolution = br.ReadInt32() / MToInch;
+                }
+                else
+                {
+                    horizontalResolution = verticalResolution = 1;
+                }
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+    internal static bool IsBmp(BinaryReader br, out string sign)
+    {
+        try
+        {
+            br.BaseStream.Seek(0, SeekOrigin.Begin);
+            sign = Encoding.ASCII.GetString(br.ReadBytes(2));    //BM for a Windows bitmap
+            return (sign == "BM" || sign == "BA" || sign == "CI" || sign == "CP" || sign == "IC" || sign == "PT");
+        }
+        catch
+        {
+            sign = null;
+            return false;
+        }
+    }
+
+    #region Ico
+
+    private static bool IsIcon(MemoryStream ms, ref double width, ref double height)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsIco(br))
+            {
+                var imageCount = br.ReadInt16();
+                width = br.ReadByte();
+                if (width == 0) width = 256;
+                height = br.ReadByte();
+                if (height == 0) height = 256;
+                br.Close();
+                return true;
+            }
+            br.Close();
+            return false;
+        }
+    }
+
+    internal static bool IsIco(BinaryReader br)
+    {
+        br.BaseStream.Seek(0, SeekOrigin.Begin);
+        var type0 = br.ReadInt16();
+        var type1 = br.ReadInt16();
+        return type0 == 0 && type1 == 1;
+    }
+
+    #endregion Ico
+
+    #region WebP
+
+    private static bool IsWebP(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        width = height = 0;
+        horizontalResolution = verticalResolution = StandardDPI * (1 + 1 / 3); //Excel seems to render webp at 1 1/3 size.
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsWebP(br))
+            {
+                var vp8 = Encoding.ASCII.GetString(br.ReadBytes(4));
+                switch (vp8)
+                {
+                    case "VP8 ":
+                        var b = br.ReadBytes(10);
+                        var w = br.ReadInt16();
+                        width = w & 0x3FFF;
+                        var hScale = w >> 14;
+                        var h = br.ReadInt16();
+                        height = h & 0x3FFF;
+                        hScale = h >> 14;
+                        break;
+
+                    case "VP8X":
+                        br.ReadBytes(8);
+                        b = br.ReadBytes(6);
+                        width = BitConverter.ToInt32(new byte[] { b[0], b[1], b[2], 0 }, 0) + 1;
+                        height = BitConverter.ToInt32(new byte[] { b[3], b[4], b[5], 0 }, 0) + 1;
+                        break;
+
+                    case "VP8L":
+                        br.ReadBytes(5);
+                        b = br.ReadBytes(4);
+                        width = (b[0] | (b[1] & 0x3F) << 8) + 1;
+                        height = (b[1] >> 6 | b[2] << 2 | (b[3] & 0x0F) << 10) + 1;
+                        break;
+                }
+            }
+        }
+        return width != 0 && height != 0;
+    }
+
+    internal static bool IsWebP(BinaryReader br)
+    {
+        try
+        {
+            br.BaseStream.Seek(0, SeekOrigin.Begin);
+            var riff = Encoding.ASCII.GetString(br.ReadBytes(4));
+            var length = GetInt32BigEndian(br);
+            var webP = Encoding.ASCII.GetString(br.ReadBytes(4));
+
+            return riff == "RIFF" && webP == "WEBP";
+        }
+        catch
+        {
+            return false;
+        }
+    }
+
+    #endregion WebP
+
+    #region Tiff
+
+    private static bool IsTif(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            return ReadTiffHeader(br, ref width, ref height, ref horizontalResolution, ref verticalResolution);
+        }
+    }
+
+    private static bool ReadTiffHeader(BinaryReader br, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        var ms = br.BaseStream;
+        var pos = ms.Position;
+        if (IsTif(br, out bool isBigEndian, false))
+        {
+            var offset = GetTifInt32(br, isBigEndian);
+            ms.Position = pos + offset;
+            var numberOfIdf = GetTifInt16(br, isBigEndian);
+            var ifds = new List<TifIfd>();
+            for (int i = 0; i < numberOfIdf; i++)
+            {
+                var ifd = new TifIfd()
+                {
+                    Tag = GetTifInt16(br, isBigEndian),
+                    Type = GetTifInt16(br, isBigEndian),
+                    Count = GetTifInt32(br, isBigEndian),
+                };
+                if (ifd.Type == 1 || ifd.Type == 2 || ifd.Type == 6 || ifd.Type == 7)
+                {
+                    ifd.ValueOffset = br.ReadByte();
+                    br.ReadBytes(3);
+                }
+                else if (ifd.Type == 3 || ifd.Type == 8)
+                {
+                    ifd.ValueOffset = GetTifInt16(br, isBigEndian);
+                    br.ReadBytes(2);
+                }
+                else
+                {
+                    ifd.ValueOffset = GetTifInt32(br, isBigEndian);
+                }
+                ifds.Add(ifd);
+            }
+
+            int resolutionUnit = 2;
+            foreach (var ifd in ifds)
+            {
+                switch (ifd.Tag)
+                {
+                    case 0x100:
+                        width = ifd.ValueOffset;
+                        break;
+
+                    case 0x101:
+                        height = ifd.ValueOffset;
+                        break;
+
+                    case 0x11A:
+                        ms.Position = ifd.ValueOffset + pos;
+                        var l1 = GetTifInt32(br, isBigEndian);
+                        var l2 = GetTifInt32(br, isBigEndian);
+                        horizontalResolution = l1 / l2;
+                        break;
+
+                    case 0x11B:
+                        ms.Position = ifd.ValueOffset + pos;
+                        l1 = GetTifInt32(br, isBigEndian);
+                        l2 = GetTifInt32(br, isBigEndian);
+                        verticalResolution = l1 / l2;
+                        break;
+
+                    case 0x128:
+                        resolutionUnit = ifd.ValueOffset;
+                        break;
+                }
+            }
+            if (resolutionUnit == 1)
+            {
+                horizontalResolution *= CmToInch;
+                verticalResolution *= CmToInch;
+            }
+        }
+        return width != 0 && height != 0;
+    }
+
+    private static bool IsTif(BinaryReader br, out bool isBigEndian, bool resetPos = false)
+    {
+        try
+        {
+            if (resetPos)
+            {
+                br.BaseStream.Position = 0;
+            }
+            var b = br.ReadBytes(2);
+            isBigEndian = Encoding.ASCII.GetString(b) == "MM";
+            var identifier = GetTifInt16(br, isBigEndian);
+            if (identifier == 42)
+            {
+                return true;
+            }
+        }
+        catch
+        {
+            isBigEndian = false;
+            return false;
+        }
+        return false;
+    }
+
+    private static short GetTifInt16(BinaryReader br, bool isBigEndian)
+    {
+        if (isBigEndian)
+        {
+            return GetInt16BigEndian(br);
+        }
+        else
+        {
+            return br.ReadInt16();
+        }
+    }
+
+    private static int GetTifInt32(BinaryReader br, bool isBigEndian)
+    {
+        if (isBigEndian)
+        {
+            return GetInt32BigEndian(br);
+        }
+        else
+        {
+            return br.ReadInt32();
+        }
+    }
+
+    #endregion Tiff
+
+    #region Emf
+
+    private static bool IsEmf(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsEmf(br))
+            {
+                var length = br.ReadInt32();
+                var bounds = new int[4];
+                bounds[0] = br.ReadInt32();
+                bounds[1] = br.ReadInt32();
+                bounds[2] = br.ReadInt32();
+                bounds[3] = br.ReadInt32();
+                var frame = new int[4];
+                frame[0] = br.ReadInt32();
+                frame[1] = br.ReadInt32();
+                frame[2] = br.ReadInt32();
+                frame[3] = br.ReadInt32();
+
+                var signatureBytes = br.ReadBytes(4);
+                var signature = Encoding.ASCII.GetString(signatureBytes);
+                if (signature.Trim() == "EMF")
+                {
+                    var version = br.ReadUInt32();
+                    var size = br.ReadUInt32();
+                    var records = br.ReadUInt32();
+                    var handles = br.ReadUInt16();
+                    var reserved = br.ReadUInt16();
+
+                    var nDescription = br.ReadUInt32();
+                    var offDescription = br.ReadUInt32();
+                    var nPalEntries = br.ReadUInt32();
+                    var device = new uint[2];
+                    device[0] = br.ReadUInt32();
+                    device[1] = br.ReadUInt32();
+
+                    var mm = new uint[2];
+                    mm[0] = br.ReadUInt32();
+                    mm[1] = br.ReadUInt32();
+
+                    //Extension 1
+                    var cbPixelFormat = br.ReadUInt32();
+                    var offPixelFormat = br.ReadUInt32();
+                    var bOpenGL = br.ReadUInt32();
+
+                    //Extension 2
+                    var hr = br.ReadUInt32();
+                    var vr = br.ReadUInt32();
+
+                    var id = br.ReadInt32();
+                    var size2 = br.ReadInt32();
+
+                    width = (bounds[2] - bounds[0] + 1);
+                    height = (bounds[3] - bounds[1] + 1);
+
+                    horizontalResolution = width / ((frame[2] - frame[0]) * HundredthThMmToInch * StandardDPI) * StandardDPI;
+                    verticalResolution = height / ((frame[3] - frame[1]) * HundredthThMmToInch * StandardDPI) * StandardDPI;
+
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static bool IsEmf(BinaryReader br)
+    {
+        br.BaseStream.Position = 0;
+        var type = br.ReadInt32();
+        return type == 1;
+    }
+
+    #endregion Emf
+
+    #region Wmf
+
+    private const double PIXELS_PER_TWIPS = 1D / 15D;
+    private const double DEFAULT_TWIPS = 1440D;
+
+    private static bool IsWmf(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            if (IsWmf(br))
+            {
+                var HWmf = br.ReadInt16();
+                var bounds = new ushort[4];
+                bounds[0] = br.ReadUInt16();
+                bounds[1] = br.ReadUInt16();
+                bounds[2] = br.ReadUInt16();
+                bounds[3] = br.ReadUInt16();
+
+                var inch = br.ReadInt16();
+                width = bounds[2] - bounds[0];
+                height = bounds[3] - bounds[1];
+                if (inch != 0)
+                {
+                    width *= (DEFAULT_TWIPS / inch) * PIXELS_PER_TWIPS;
+                    height *= (DEFAULT_TWIPS / inch) * PIXELS_PER_TWIPS;
+                }
+                return width != 0 && height != 0;
+            }
+        }
+        return false;
+    }
+
+    private static bool IsWmf(BinaryReader br)
+    {
+        br.BaseStream.Position = 0;
+        var key = br.ReadUInt32();
+        return key == 0x9AC6CDD7;
+    }
+
+    #endregion Wmf
+
+    #region Png
+
+    private static bool IsPng(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
+    {
+        using (var br = new BinaryReader(ms))
+        {
+            return IsPng(br, ref width, ref height, ref horizontalResolution, ref verticalResolution);
+        }
+    }
+
+    private static bool IsPng(BinaryReader br, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution, long fileEndPosition = long.MinValue)
+    {
+        if (IsPng(br))
+        {
+            if (fileEndPosition == long.MinValue)
+            {
+                fileEndPosition = br.BaseStream.Length;
+            }
+            while (br.BaseStream.Position < fileEndPosition)
+            {
+                var chunkType = ReadPngChunkHeader(br, out int length);
+                switch (chunkType)
+                {
+                    case "IHDR":
+                        width = GetInt32BigEndian(br);
+                        height = GetInt32BigEndian(br);
+                        br.ReadBytes(5); //Ignored bytes, Depth compression etc.
+                        break;
+
+                    case "pHYs":
+                        horizontalResolution = GetInt32BigEndian(br);
+                        verticalResolution = GetInt32BigEndian(br);
+                        var unitSpecifier = br.ReadByte();
+                        if (unitSpecifier == 1)
+                        {
+                            horizontalResolution /= MToInch;
+                            verticalResolution /= MToInch;
+                        }
+
+                        br.Close();
+                        return true;
+
+                    default:
+                        br.ReadBytes(length);
+                        break;
+                }
+                var crc = br.ReadInt32();
+            }
+        }
+        br.Close();
+        return width != 0 && height != 0;
+    }
+
+    private static bool IsPng(BinaryReader br)
+    {
+        br.BaseStream.Position = 0;
+        var signature = br.ReadBytes(8);
+        return signature.SequenceEqual(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 });
+    }
+
+    private static string ReadPngChunkHeader(BinaryReader br, out int length)
+    {
+        length = GetInt32BigEndian(br);
+        var b = br.ReadBytes(4);
+        var type = Encoding.ASCII.GetString(b);
+        return type;
+    }
+
+    #endregion Png
+
+    #region Svg
+
+    private static bool IsSvg(MemoryStream ms, ref double width, ref double height)
+    {
+        try
+        {
+            using (var reader = new XmlTextReader(ms))
+            {
+                while (reader.Read())
+                {
+                    if (reader.LocalName == "svg" && reader.NodeType == XmlNodeType.Element)
+                    {
+                        var w = reader.GetAttribute("width");
+                        var h = reader.GetAttribute("height");
+                        var vb = reader.GetAttribute("viewBox");
+                        reader.Close();
+                        if (w == null || h == null)
+                        {
+                            if (vb == null)
+                            {
+                                return false;
+                            }
+                            var bounds = vb.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
+                            if (bounds.Length < 4)
+                            {
+                                return false;
+                            }
+                            if (string.IsNullOrEmpty(w))
+                            {
+                                w = bounds[2];
+                            }
+                            if (string.IsNullOrEmpty(h))
+                            {
+                                h = bounds[3];
+                            }
+                        }
+                        width = GetSvgUnit(w);
+                        if (double.IsNaN(width)) return false;
+                        height = GetSvgUnit(h);
+                        if (double.IsNaN(height)) return false;
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+        catch
+        {
+            return false;
+        }
+    }
+
+    private static bool IsSvg(Stream ms)
+    {
+        try
+        {
+            ms.Position = 0;
+            using var reader = new XmlTextReader(ms);
+            while (reader.Read())
+            {
+                if (reader.LocalName == "svg" && reader.NodeType == XmlNodeType.Element)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+        catch
+        {
+            return false;
+        }
+    }
+
+    private static double GetSvgUnit(string v)
+    {
+        var factor = 1D;
+        if (v.EndsWith("px", StringComparison.OrdinalIgnoreCase))
+        {
+            v = v.Substring(0, v.Length - 2);
+        }
+        else if (v.EndsWith("pt", StringComparison.OrdinalIgnoreCase))
+        {
+            factor = 1.25;
+            v = v.Substring(0, v.Length - 2);
+        }
+        else if (v.EndsWith("pc", StringComparison.OrdinalIgnoreCase))
+        {
+            factor = 15;
+            v = v.Substring(0, v.Length - 2);
+        }
+        else if (v.EndsWith("mm", StringComparison.OrdinalIgnoreCase))
+        {
+            factor = 3.543307;
+            v = v.Substring(0, v.Length - 2);
+        }
+        else if (v.EndsWith("cm", StringComparison.OrdinalIgnoreCase))
+        {
+            factor = 35.43307;
+            v = v.Substring(0, v.Length - 2);
+        }
+        else if (v.EndsWith("in", StringComparison.OrdinalIgnoreCase))
+        {
+            factor = 90;
+            v = v.Substring(0, v.Length - 2);
+        }
+        if (double.TryParse(v, out double value))
+        {
+            return value * factor;
+        }
+        return double.NaN;
+    }
+
+    #endregion Svg
+
+    private static ushort GetUInt16BigEndian(BinaryReader br)
+    {
+        var b = br.ReadBytes(2);
+        return BitConverter.ToUInt16(new byte[] { b[1], b[0] }, 0);
+    }
+
+    private static short GetInt16BigEndian(BinaryReader br)
+    {
+        var b = br.ReadBytes(2);
+        return BitConverter.ToInt16(new byte[] { b[1], b[0] }, 0);
+    }
+
+    private static int GetInt32BigEndian(BinaryReader br)
+    {
+        var b = br.ReadBytes(4);
+        return BitConverter.ToInt32(new byte[] { b[3], b[2], b[1], b[0] }, 0);
+    }
+}

+ 1 - 2
Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

@@ -3,7 +3,7 @@
         <TargetFrameworks>netstandard2.0;netstandard2.1;net461;net5;net6</TargetFrameworks>
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-        <Version>1.1.2.2</Version>
+        <Version>1.2</Version>
         <Authors>懒得勤快</Authors>
         <Description>Masuit.Tools.Excel导出库,支持一些简单数据的导出,支持图片列</Description>
         <Copyright>懒得勤快</Copyright>
@@ -32,7 +32,6 @@
         <PackageReference Include="EPPlus" Version="6.0.5" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
         <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
-        <PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
     </ItemGroup>
 
 </Project>