使用 excel introp 或 npoi 从 excel(带有行和单元格位置)读取图像

jit*_*der 1 c# excel-interop npoi

我需要使用开始和结束行号从 excel 中提取图像。并开始 && 结束 col no

我目前的代码如下:-

  var excelApp = new Application();
  var wb = excelApp.Workbooks.Open(filePath, Type.Missing, Type.Missing, 
          Type.Missing, Type.Missing, Type.Missing, Type.Missing,
          Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
          Type.Missing, Type.Missing, Type.Missing, Type.Missing);
  var ws = (Worksheet)wb.Worksheets["Sheet1"];
   int startCol = 0;
   int startRow =0;
   int endCol = 0;
   int endRow = 0;
  foreach (var pic in ws.Pictures())
                    {
                        int startCol = pic.TopLeftCell.Column;
                        int startRow = pic.TopLeftCell.Row;
                        int endCol = pic.BottomRightCell.Column;
                        int endRow = pic.BottomRightCell.Row;
                     }
Run Code Online (Sandbox Code Playgroud)

当所有图像都不同时,上面的代码工作正常,但是当我将相同的图像放在不同的单元格中时,它只选择第一个。

例如,当我put abc.jpeg at B1 cell and xyz.jpeg at C5 cell当时工作正常results are two object first startRow=1,endRow=1,startCol=1,endCol=1 and second startRow=5,endRow=5,startCol=2,endCol=2

但是,如果我put abc.jpeg at B1 cell and C5 cellresult is one objectstartRow=1,endRow=1,startCol=1,endCol=1两个images.It不PIC第二图像。

为什么会这样? 有没有使用 interop 或 npoi 的解决方案

Sco*_*nen 5

TL;DR - NPOI 的行为与 Excel Interop 相同,当同一图像添加两次时返回一张图像。出于同样的原因,它可能会这样做。EPPlus(本文中的最后一个测试)以您期望的方式处理这种情况,分别识别图片的两个实例并返回它们在工作表上的位置。

我首先尝试使用 NPOI。我创建了一个工作簿并将相同的图片插入到两个位置的第一张工作表中。

-----
|   |
-----

    -----
    |   |
    -----
Run Code Online (Sandbox Code Playgroud)

使用非营利组织

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NPOI.XSSF.UserModel;
using System.IO;

namespace ExcelImageTests
{
    [TestClass]
    public class NpoiExcelImages
    {
        [TestMethod]
        public void FindsTwoDistinctImagesInFile()
        {
            XSSFWorkbook workbook;
            using (var file = new FileStream(@"C:\Users\path-to-my-file\sotest.xlsx", 
                FileMode.Open, FileAccess.Read))
            {
                workbook = new XSSFWorkbook(file);
            }
            var pictures = workbook.GetAllPictures();
            Assert.AreEqual(2, pictures.Count);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我对 NPOI 的了解。测试失败。NPOI 计算一张图片,而不是两张。奇怪的是,它也没有参考图纸级别的形状、图片或绘图。返回的图片属于类型XSSFPictureData并包含图片的二进制数据。它不是指工作表和图片之间的关系。我怀疑这就是为什么它只返回一个的原因。一个图像嵌入了两次。

为了确认我添加了另一张不同于前两张的图片。现在测试通过了。工作表上有三张图片可见,但由 返回的两张不同的图片GetAllPictures()

您提到了 Interop 和 NPOI,但另一个选择是 EPPlus。它更常用,在使用 NPOI 几分钟后,我明白了原因。NPOI 返回很多object类型,就像 Excel Interop 一样,您必须知道它们是什么,以便您可以将它们转换为这些类型。

EPPlus 好很多。这是与EPPlus相同的测试:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using OfficeOpenXml;
using System.IO;

namespace ExcelImageTests
{
    [TestClass]
    public class EPPlusExcelImages
    {
        [TestMethod]
        public void FindsTwoDistinctImagesInFile()
        {
            var file = new FileInfo(@"C:\Users\path-to-my-file\sotest.xlsx");
            using (var package = new ExcelPackage(file))
            {
                var workbook = package.Workbook;
                var sheet = workbook.Worksheets[1];
                Assert.AreEqual(2, sheet.Drawings.Count)
                var drawingOne = sheet.Drawings[0];
                var drawingTwo = sheet.Drawings[1];
                // From returns the position of the upper left corner of the picture.
                // To returns the position of the lower right corner.
                Assert.IsTrue(drawingOne.From.Row < drawingTwo.From.Row);
                Assert.IsTrue(drawingOne.From.Column < drawingTwo.From.Column);
                Assert.IsTrue(drawingOne.To.Row < drawingTwo.To.Row);
                Assert.IsTrue(drawingOne.To.Column < drawingTwo.To.Column);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此测试通过。它检测两个图像,并正确地告诉我它们的相对位置。你没有我的工作表,但我检查过,行和列都是正确的。

一个奇怪的细节是工作表索引是从 1 开始的,但行和列是从 0 开始的。但这没什么大不了的。

此外,虽然从包返回的所有对象都是IDisposable,但大多数示例只显示了处理包本身。一个人指出,Dispose其他对象的方法是空的。这很奇怪。但它仍然比 Excel Interop 更好,您必须在其中发布 COM 对象。