欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#導(dǎo)入EXCEL時如何讀取單元格中的圖片(WPS)

 更新時間:2025年04月29日 09:33:13   作者:@夢想家@  
這篇文章主要介紹了C#導(dǎo)入EXCEL時如何讀取單元格中的圖片(WPS)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

C#導(dǎo)入EXCEL時讀取單元格中的圖片(WPS)

起因

最新要做一個excel批量導(dǎo)入商品的功能,但是文本內(nèi)容好讀取,但是圖片文件在網(wǎng)上沒有找到比較好的解決辦法

解決方案1

(不推薦)先導(dǎo)入excel數(shù)據(jù),再通過文件夾/壓縮包的方式導(dǎo)入圖片,但是這樣比較麻煩,如果說excel表格后續(xù)還需要維護(hù)的話,對于做excel表格的同學(xué)來說不太友好

解決方案2

解壓縮excel文件,可以得到對應(yīng)的文件夾,如下圖所示的內(nèi)容,其中xl文件夾下存在幾個數(shù)據(jù)文件,可以手動拼接起來,下面著重說一下該如何一步步實現(xiàn)指定單元格的文件讀取

1)上傳excel文件

定義好接受類,我的類是這樣,可以根據(jù)自己需要進(jìn)行修改

/// <summary>
/// 導(dǎo)入產(chǎn)品dto
/// </summary>
public class ImportSoftProductDto:PrimaryKey
{
    /// <summary>
    /// 供應(yīng)商編號
    /// </summary>
    [ExcelColumnIndex("A")]
    public string SupplierNo { get; set; }
    /// <summary>
    /// 產(chǎn)品編號
    /// </summary>
    [ExcelColumnIndex("B")]
    public string ProductNo { get; set; }
    /// <summary>
    /// 產(chǎn)品名稱
    /// </summary>
    [ExcelColumnIndex("C")]
    public string ProductName { get; set; }
    /// <summary>
    /// 主分類
    /// </summary>
    [ExcelColumnIndex("D")]
    public string MainCategory { get; set; }
    /// <summary>
    /// 次分類
    /// </summary>
    [ExcelColumnIndex("E")]
    public string SubCategory { get; set; }
    /// <summary>
    /// 采購單價
    /// </summary>
    [ExcelColumnIndex("F")]
    public decimal PurchasePrice { get; set; }
    /// <summary>
    /// 銷售單價
    /// </summary>
    [ExcelColumnIndex("G")]
    public decimal SalesPrice { get; set; }
    /// <summary>
    /// 單位
    /// </summary>
    [ExcelColumnIndex("H")]
    public string Unit { get; set; }
    /// <summary>
    /// 尺寸
    /// </summary>
    [ExcelColumnIndex("I")]
    public string Size { get; set; }
    /// <summary>
    /// 材質(zhì)報價
    /// </summary>
    [ExcelColumnIndex("J")]
    public string Texture { get; set; }
    /// <summary>
    /// 備注說明
    /// </summary>
    [ExcelColumnIndex("K")]
    public string Explain { get; set; }
    /// <summary>
    /// 圖片_DISPIMG函數(shù)字符串
    /// </summary>
    [ExcelColumnIndex("L")]
    public string IMG_DISPIMG { get; set; }
    //= DISPIMG("ID_498B62A4F63D447D9F9E1640DAF57A45", 1)
    public string DISPIMG_Id
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(IMG_DISPIMG))
            {
                var split = IMG_DISPIMG.Split('"');
                return split[1];
            }
            else
            {
                return "";
            }
        }
    }
    /// <summary>
    /// 圖片原始路徑
    /// </summary>
    public string ImgOriginalUrl { get; set; }
    /// <summary>
    /// 圖片最終路徑
    /// </summary>
    public string ImgFinalUrl { get; set; }
    public string ImgSuffix
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(ImgOriginalUrl))
            {
                return Path.GetExtension(ImgOriginalUrl).ToLower().Replace(".", "");
            }
            else
            {
                return string.Empty;
            }
        }
    }
}

2)讀取excel文件內(nèi)容,這里使用的是MiniExcel,可以在nuget中安裝

注意:wps嵌入的圖片可以通過string得到如下的字符串=DISPIMG("ID_8C72DF5CE3FA413298278785876E9D65",1),其中,ID_8C72DF5CE3FA413298278785876E9D65是我們需要的東東

var rows = MiniExcel.Query<ImportSoftProductDto>(absoluteUrl, startCell: "A3").ToList();

3)解壓縮excel

需要用到命名空間:System.IO.Compression,這里,我是直接以該excel的文件名作為解壓文件夾的

var zipFileDirectory = absoluteUrl.Substring(0, absoluteUrl.LastIndexOf("."));
ZipFile.ExtractToDirectory(absoluteUrl, zipFileDirectory);

4)讀取cellimages.xml內(nèi)容,該文件位于xl文件夾下

var cellimagesXML = File.ReadAllText(Path.Combine(zipFileDirectory, "xl/cellimages.xml"));

5)讀取cellimages.xml.rels內(nèi)容

var cellimagesXMLRels = File.ReadAllText(Path.Combine(zipFileDirectory, "xl/_rels/cellimages.xml.rels"));

6)結(jié)合2個文件內(nèi)容和圖片資源名稱

計算出第二步中ID_8C72DF5CE3FA413298278785876E9D65對應(yīng)的圖片,這里也可以自己解析xml內(nèi)容,主要是為了獲得他們直接的對應(yīng)關(guān)系

var imgList = new List<ImportSoftProductImgDto>();

var nodes_XML = XElement.Parse(cellimagesXML);
foreach (var xNode in nodes_XML.DescendantNodes().OfType<XCData>().ToList())
{
    xNode.Parent.Add(xNode.Value);
    xNode.Remove();
}
var json_XML = JObject.Parse(JsonConvert.SerializeXNode(nodes_XML, Formatting.Indented));
foreach (var item in json_XML["etc:cellImages"]["etc:cellImage"])
{
    var DISPIMG_Id = item["xdr:pic"]["xdr:nvPicPr"]["xdr:cNvPr"]["@name"].ToString();
    var id = item["xdr:pic"]["xdr:blipFill"]["a:blip"]["@r:embed"].ToString();

    imgList.Add(new ImportSoftProductImgDto
    {
        Id = id,
        Target = string.Empty,
        DISPIMG_Id = DISPIMG_Id
    });
}

var nodes_XMLRels = XElement.Parse(cellimagesXMLRels);
foreach (var xNode in nodes_XMLRels.DescendantNodes().OfType<XCData>().ToList())
{
    xNode.Parent.Add(xNode.Value);
    xNode.Remove();
}
var json_XMLRels = JObject.Parse(JsonConvert.SerializeXNode(nodes_XMLRels, Formatting.Indented));

foreach (var item in json_XMLRels["Relationships"]["Relationship"])
{
    var id = item["@Id"].ToString();
    var target = item["@Target"].ToString();
    //可能公用一張圖片
    foreach (var imgItem in imgList.Where(o => o.Id == id))
    {
        imgItem.Target = target;
    }
}

7)遍歷賦值圖片路徑

foreach (var item in rows)
{
    item.ImgOriginalUrl = imgList.FirstOrDefault(o => o.DISPIMG_Id == item.DISPIMG_Id)?.Target;
}

8)接下來就是圖片上傳到新地址的方式了

這里是我的上傳實現(xiàn)

foreach (var item in rows)
{
    if (!string.IsNullOrWhiteSpace(item.ImgOriginalUrl))
    {
        var suffix = Path.GetExtension(item.ImgOriginalUrl).ToLower().Replace(".", "");//文件后綴
        var relativePath = Path.Combine("uploads", suffix, DateTime.Now.ToString("yyyyMM"));//相對路徑
        var fileName = Guid.NewGuid().ToString("N") + "." + suffix;//圖片重命名

        var absolutePath = Path.Combine(App.HostEnvironment.ContentRootPath, relativePath);//絕對路徑

        if (!Directory.Exists(absolutePath))
        {
            Directory.CreateDirectory(absolutePath);
        }

        FileInfo file = new FileInfo(Path.Combine(zipFileDirectory, "xl", item.ImgOriginalUrl));
        if (file.Exists) //可以判斷源文件是否存在
        {
            // 這里是true的話覆蓋
            file.CopyTo(Path.Combine(absolutePath, fileName), true);
            item.ImgFinalUrl = Path.Combine(_appInfo.Host, relativePath, fileName).Replace("\\", "/");
        }
    }
}

9)至此,就可以往數(shù)據(jù)庫里插入數(shù)據(jù)了

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入理解C#委托delegate的使用

    深入理解C#委托delegate的使用

    本文主要介紹了C#委托delegate的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • unity實現(xiàn)簡單抽獎系統(tǒng)

    unity實現(xiàn)簡單抽獎系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了unity實現(xiàn)簡單抽獎系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#算法之整數(shù)反轉(zhuǎn)

    C#算法之整數(shù)反轉(zhuǎn)

    這篇文章介紹了C#算法之整數(shù)反轉(zhuǎn),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • 詳解C#中委托的概念與使用

    詳解C#中委托的概念與使用

    委托這個名字取的神乎其神的,但實質(zhì)是函數(shù)式編程,把函數(shù)作為參數(shù)傳遞給另一個參數(shù)。這篇文章主要為大家介紹一下C#中委托的概念與使用,需要的可以參考一下
    2023-02-02
  • C#非矩形窗體實現(xiàn)方法

    C#非矩形窗體實現(xiàn)方法

    這篇文章主要介紹了C#非矩形窗體實現(xiàn)方法,涉及C#窗體操作的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • C#動態(tài)創(chuàng)建button的方法

    C#動態(tài)創(chuàng)建button的方法

    這篇文章主要介紹了C#動態(tài)創(chuàng)建button的方法,涉及C#按鈕屬性動態(tài)設(shè)置的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • c# 網(wǎng)址壓縮簡單實現(xiàn)短網(wǎng)址

    c# 網(wǎng)址壓縮簡單實現(xiàn)短網(wǎng)址

    短網(wǎng)址,忽然一下子就冒出來的東西,長長的一個URL,提交過去,出來就只有短短的一個URL了,看起來似乎挺神奇,其實簡單分析一下,明白其中的原理,也是一件很簡單的事情,需要的朋友可以了解下
    2012-12-12
  • c# 實現(xiàn)IComparable、IComparer接口、Comparer類的詳解

    c# 實現(xiàn)IComparable、IComparer接口、Comparer類的詳解

    本篇文章是對c#中實現(xiàn)IComparable、IComparer接口、Comparer類進(jìn)行了詳細(xì)的分析詳解,需要的朋友參考下
    2013-05-05
  • 字符串內(nèi)存駐留機(jī)制詳解示例

    字符串內(nèi)存駐留機(jī)制詳解示例

    字符串內(nèi)存駐留機(jī)制詳解示例,大家參考使用吧
    2013-12-12
  • c# 獲取機(jī)器唯一識別碼的示例

    c# 獲取機(jī)器唯一識別碼的示例

    這篇文章主要介紹了c# 獲取機(jī)器唯一識別碼的示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03

最新評論