C#獲取excel中的圖片,保存到本地文件夾


最近開發一個功能,從excel中批量導入數據到數據庫中,而excel中的內容中包含圖片。如果沒有包含圖片的話,只是純文本信息,網上已經有很多例子,我就不寫了。我想寫的是,讀取excel中每行特定列的的圖片。

Excel 2007文件 如下:

把該excel文件的后綴名(xlsx)改成zip 或者rnr,我把它改成zip,解壓后你就會發現,excel也就是多個xml文件組成的,所以,很顯然,我們只解析xml文件,就能找到圖片了。

解壓后的excel文件如下:

Excel中的圖片信息都在文件夾xl里面,點擊進去就可以看到以下內容:

圖片就保存在media這個文件夾里面,而獲取圖片要解析的xml,在drawings文件夾里面,所以當要解析xml獲取圖片信息時,可以通過判斷drawings文件夾或者media 文件夾存不存在,來控制程序的執行。如果excel中不存在其中的一個,表明excel中是不存在圖片的,都是文本信息。

                  圖1

media文件夾中存放着excel的圖片,只是名字按添加的順序依次改為image1、image2……,如果添加的圖片相同的話,meida只保存一個,excel會判斷名字添加的圖片名字相同不。這里強調一下,excel中的圖片信息的位置關系,是按照在excel中插入圖片的順序排列的,並不是按照行號來排列,以為圖片和單元格沒有附屬關系、依附關系。

 

3.解析drawings文件夾的xml。drawings文件夾中包含drawing1.xml 和_rels文件夾。

drawings.xml 在瀏覽器中的xml代碼如下(直接把這個文件拖到瀏覽器中就可以看到),我們只看一張圖片的,每一張圖片以xdr:twoCellAnchor標簽分隔開。

只截取有用的xml信息,如圖所示:

                     圖2

然后在看看_rels文件夾中的drawing1.xml.rels的xml信息。如下圖所示:

                                 圖3

從上面三張圖中,我們不難發現一些規則,以下一一解釋:

圖1是media文件夾,是存圖片的。

圖2是drawings.xml,是存圖片在excel中的位置等信息。<xdr:from>這個標簽和<xdr:to> 是對應的,這兩個標簽中都有 <xdr:col>和<xdr:row>,col也就是colum(列),而row(行);<xdr:from>表示圖片從第幾行第幾列 <xdr:to>到 第幾行第幾列,也就是圖片在excel中的覆蓋范圍。這個例子是圖片只能保存在一個單元格內,所以只取from里面的row就知道該圖片屬於哪行了,列都是固定的(Picutre)。在看看row和col的數字,跟excel中的對比一下,在xml中,row和col索引都是從0開始的。

 

再看<xdr:blipFill>下的子節點<xdr:blipFill>中的<a:blip r:embed="rId1"/>,和圖3對比一下,就可以知道圖片存在哪個文件夾下的哪種圖片。

 

以上是思路,實現代碼如下:

 

把excel文件復制一份,並把后綴名改成zip,可以通過File.Copy()函數實現

 

string oriFile = @"D:\picture.xlsx";

string destFile = @"D:\picture.zip";

File.Copy(oriFile,destFile,true);

 

 

解壓picture.zip文件

using ICSharpCode.SharpZipLib.Zip; //這個類庫可以去下載。

 

string err = "";
        /// <summary>  
        /// 功能:解壓zip格式的文件。  
        /// </summary>  
        /// <param name="zipFilePath">壓縮文件路徑</param>  
        /// <param name="unZipDir">解壓文件存放路徑,為空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾</param>  
        /// <param name="err">出錯信息</param>  
        /// <returns>解壓是否成功</returns>  
        public static bool UnZipFile(string zipFilePath, string unZipDir, out string err)
        {
            err = "";
            if (zipFilePath == string.Empty)
            {
                err = "壓縮文件不能為空!";
                return false;
            }
            if (!File.Exists(zipFilePath))
            {
                err = "壓縮文件不存在!";
                return false;
            }
            //解壓文件夾為空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾  
            if (unZipDir == string.Empty)
                unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
            if (!unZipDir.EndsWith("//"))
                unZipDir += "//";
            if (!Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);

            try
            {
                using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
                {

                    ZipEntry theEntry;
                    while ((theEntry = s.GetNextEntry()) != null)
                    {
                        string directoryName = Path.GetDirectoryName(theEntry.Name);
                        string fileName = Path.GetFileName(theEntry.Name);
                        if (directoryName.Length > 0)
                        {
                            Directory.CreateDirectory(unZipDir + directoryName);
                        }
                        if (!directoryName.EndsWith("//"))
                            directoryName += "//";
                        if (fileName != String.Empty)
                        {
                            using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
                            {

                                int size = 2048;
                                byte[] data = new byte[2048];
                                while (true)
                                {
                                    size = s.Read(data, 0, data.Length);
                                    if (size > 0)
                                    {
                                        streamWriter.Write(data, 0, size);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }//while  
                }
            }
            catch (Exception ex)
            {
                err = ex.Message;
                return false;
            }
            
            return true;
        }

 

 

 

解析Xml

 

string XMLExcelPath = @"D:\picture\xl\drawings\drawing1.xml";Dictionary<string, string> picRowDictionary = new Dictionary<string, string>();//保存行號和圖片的屬性rId

        private void FromXMLBtn_Click(object sender, EventArgs e)

        {

            XmlDocument xdoc = new XmlDocument();

            xdoc.Load(XMLExcelPath);

            //獲取根節點

            XmlNode root = xdoc.DocumentElement;

            //獲取根節點下的所有子節點

            XmlNodeList nodeList = root.ChildNodes;

            //循環遍歷每一個子節點

            foreach (XmlNode nl in nodeList)

            {

                XmlElement sondNode = (XmlElement)nl;

                XmlNodeList descendDodeList = sondNode.ChildNodes;

                XmlNodeList fromNodeList = descendDodeList[0].ChildNodes;

                //取得行號

                string row = fromNodeList.Item(2).InnerText.Trim();

 

                XmlNodeList picNodeList = descendDodeList[2].ChildNodes;

                XmlNodeList blipFillNodeList = picNodeList[1].ChildNodes;

                XmlElement picElement =(XmlElement)blipFillNodeList.Item(0);

                string picturePath = picElement.GetAttribute("r:embed").ToString();

                picRowDictionary.Add(row,picturePath);

               

            }

 

            GetPicture(picRowDictionary);

        }

 

//獲取圖片,並把圖片copy出來

        string pictPath = @"D:\picture\xl\drawings\_rels\drawing1.xml.rels";

        string dir = @"D:\picture\xl";

        string pathOfPicture = string.Empty;

        Dictionary<string,string> rowAndNewPicPath=new Dictionary<string,string>();

        public Dictionary<string,string>  GetPicture (Dictionary<string,string> dic)

        {

            if (dic.Count <= 0) return null;

            XmlDocument doc = new XmlDocument();

            doc.Load(pictPath);

 

            XmlNode root = doc.DocumentElement;

            XmlNodeList nlist = root.ChildNodes;

            foreach (KeyValuePair<string, string> kvp in dic)

            {

                foreach(XmlNode xn in nlist)

                {

                    XmlElement xe = (XmlElement)xn;

                    if (xe.GetAttribute("Id").ToString() == kvp.Value)

                    {

                        pathOfPicture = xe.GetAttribute("Target").ToString().Replace("..","").Replace("/",@"\");

                        pathOfPicture = dir + pathOfPicture;

                       CopyPicture(kvp.Key,pathOfPicture,rowAndNewPicPath);

                        break;

                    }

                }

            }

            return rowAndNewPicPath;

        }

 

//根據路徑獲取圖片

        public void CopyPicture(string row,string path,Dictionary<string, string> d)

        {

           string name=Path.GetFileNameWithoutExtension(path);

           if (!Directory.Exists(@"D:\resource"))

           {

               Directory.CreateDirectory(@"D:\resource");

           }

            File.Copy(path,@"D:\resource\"+name+".jpg",true);

            d.Add(row,@"D:\rosource\"+name+".jpg");

        }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM