這是《從產品角度學EXCEL》系列第三篇。html
前言請看:node
0 爲何要關注EXCEL的本質編程
1 excel是怎樣運做的ruby
或者你能夠去微信公衆號@尾巴說數 得到連載目錄。微信
本文僅由尾巴本人發佈於特定網站。不接受任何無受權轉載,如需轉載,請先聯繫我,很是感謝。網絡
這段時間,上海街邊的樹上陸陸續續長出了嫩芽,放眼望去有各類層次的綠色,格外好看。咱們今天的話題,剛好也與樹有關。只不過,樹都是往天空伸展枝葉的,而咱們這裏討論的‘樹’,倒是由根部出發,逐行逐行往下延展、伸展。數據結構
還記得上一個章節裏,咱們對一個excel文件解壓縮後,發現了若干個xml文件嗎?架構
xml本質上是一種使用樹形結構存儲信息的文檔。它由一個根節點root開始,逐層逐層長枝節,並給每一層都打了個標籤,讓xml解析器能夠快速定位信息的內容。而每一層以及每個底部的節點,都是這些信息的一個分類屬性。咱們瞭解了它們的屬性和層級,也就瞭解這顆結構樹長成什麼樣子。框架
正由於xml的結構與層級是如此重要,在進一步講單元格以前,咱們頗有必要先剖析看看excel xml樹的結構,從大致上再來理解一下excel儲存文件的方式。函數
須要注意的是,這一章節大概是整個系列裏涉及最多編程的章節了。若是各位對編程不是特別感興趣,能夠先跳過這一節,去看後面的內容。不過按照我我的的經驗來講,無論你是用excel作一些簡單的數據處理,仍是想要在數據分析行業裏走得穩妥一些,瞭解瞭解編程,只會有好處而沒有壞處。尤爲是編程的一些思想,如妥善地設計接口,分隔各個功能塊等,即便你用excel處理數據,這些也對你十分有好處。
言歸正傳吧。咱們回過頭來再看看excel解壓縮之後的xml文件。
讓咱們隨意打開一個xml文件,一串串密密麻麻的字符就這樣跳了出來。
對於不熟悉xml架構的人來講,咱們只會看到眼花繚亂的括號,等號,引號。可是若是你對xml有點理解,你就會知道,這一系列的標點符號框起了一個個xml的數據結構。
對於xml來講,每個層級都是由<標籤 屬性=ABC>內容信息</標籤>構成的。有的內容信息裏又會再次嵌套一層標籤層級,重重相疊,從根部開始向下延展出了無數枝葉,構成了一棵看似錯綜複雜,倒是井井有條的xml樹。人們只要定位到某一個枝葉,就能夠迅速把這個枝葉下的特定信息取出來。而要搞懂這棵xml樹長什麼樣子,首先就要搞懂說這棵樹是有哪些層級,各個層級叫什麼,有什麼內容。
可是各位再回顧看看上面的截圖,一長串一長串的代碼,你固然能夠一個個去判斷說,啊,根標籤從worksheet開始,下面有selection層級,有f層級等等,可是這樣子作,不只低效,並且會有遺漏。
請各位在學習excel時,隨時記住一個原則,那就是能夠不要手工去作的事情,就不要手工去作。寧願本身腦子廢點腦力構思最優方法,也不要直接就開始機械的做業。
那麼,在這裏,面臨這個要人工一個個看標籤的艱鉅任務時,咱們該如何是好呢?
在這裏跟你們再普及一個概念的是,xml嘛,除了微軟在用於office系列文檔儲存格式之外,它還普遍應用於各類網頁設計領域。而在網頁獲取信息這一塊,咱們自然有不少工具能夠經過讀取html或者xml源代碼,解析它們的結構,進行數據提取工做(高級點叫法即網絡爬蟲)
因此對於這裏的excel xml源文件,咱們天然能夠應用各類爬蟲工具,把xml的框架給找出來。
我 用的比較熟的應該是R語言的rvest包爬蟲了,查了一下它的文檔,有一個叫xml_structure的,能夠直接把xml文件的標籤層次給讀出來,而 xml_nodes/xml_attr等,又能夠把裏面特定的標籤內容給分層讀出來。那麼寫一段代碼,幫我把excel的xml源文件裏的層級與內容弄出 來,那就省了我很大的心力啦^^
由於R語言代碼並非咱們的重點,因此我把源代碼放在文章末尾的擴展閱讀裏了,有須要的能夠去看看,也能夠用其餘語言寫寫。有的時候只要學會一點點的編程,就能大大的改善各位的工做效率。要用好工具而不是被工具玩,是我但願在這系列excel教程裏告訴你們的一個點。
那麼言歸正傳。請各位看看下面這個用R語言跑出來的csv文件截圖。
左列是咱們的標籤名,右列是咱們標籤裏面包含的文本。經過這個文件,咱們就能夠很容易知道各個標籤裏存放了什麼文本信息。咱們會發現row下面是一串串的c/v/f。而c與v的信息幾乎徹底同樣。
另外,在r裏,咱們能夠經過xml_structure輸出xml文件的結構。這兩個結合起來,我爲各位繪製了一張sheet1.xml的樹形結構圖:
各 位能夠看到,在worksheet文件夾裏的sheet1.xml,是在sheetdata裏按照row爲標籤層級,存放了若干行的數據。而行又以 c(cell)爲導向,存放了單元格的v (value)和f(函數)。有多少行,在sheet1.xml裏就有多少row,一個row有若干個有效單元格,就會有若干個c。
從這個角度看excel,會不會對excel的產品設計層次有了進一步的理解呢?
另外,上面的截圖沒有出示的一點是,在worksheet這個文件夾裏,數字是直接存在各個sheetxxx.xml裏的,而字符類文本,倒是單獨存放在外面的SharedString.xml裏。
嘿嘿,數字和文本的存放格式不同,各位想到了什麼?有沒有虎軀一震,想到了excel裏由於數字和文本的不一樣,帶來的各類不便?
在前面囉嗦完爲何要寫這個系列,以及excel是怎麼工做之後,咱們終於把拼圖最重要的一塊——解讀xml補上了。那麼接下來,咱們終於要進入從產品角度看excel的正題。
下一章節:單元格背後的祕密,敬請期待:)
以及順手打個小廣告,本系列預計每週更新一章,工做很忙或者沒有靈感的時候可能會兩週更新一章。每次都會在個人微信公衆號上推送全部章節,歡迎關注個人公衆號。
固然,若是各位等不及更新,想更早了解後續內容的話,歡迎私下聯繫我。上海地區提供有償私教:)
HTML的基礎知識: http://www.w3school.com.cn
闡述XML樹形結構的一篇文章: http://www.cnblogs.com/iswszheng/archive/2009/05/18/1459213.html
曾經用R語言寫過的kindle爬蟲: http://www.flybi.net/blog/weibaar/2974
R語言解析XML源代碼:
setwd("~/excel/") library(rvest) #代碼用於《從產品角度學EXCEL》系列文章,XML解析 # read xml in zip files get_xmllist<-function(access){ list<-list.files(access,full.names=TRUE,pattern = "xml$",recursive = TRUE) list_name<-gsub(as.character(access),"",list) list_name<-gsub("\\/|\\.|\\[|\\]","-",list_name) list_name<-gsub("\\-\\-","-",list_name) list<-data.frame(list,list_name,stringsAsFactors = FALSE) list } # read xml structure get_structure<-function(xmlfile){ data<-xml(xmlfile,encoding="UTF-8") data<-data %>% html_nodes("*") output<-cbind(node_names=data %>% html_tag(), node_text=data %>% html_text()) output<-data.frame(output) output } write_result<-function(dataframe,name){ write.csv(dataframe,paste0("./Output/",name,".csv"),row.names=FALSE) } #use these three function xml_list<-get_xmllist("./sample u.xlsx/") for (i in 1:nrow(xml_list)){ data<-get_structure(xml_list$list[i]) write_result(data,xml_list$list_name[i]) } #write the structure xml_structure(html(xml_list$list[8]))
微信公衆號: