国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
R語(yǔ)言讀取excel2007文件(xlsx)

 

碼了幾天字,@Conda 終于讓我碼到了10000,還有10000字,停下來(lái)休息下,記錄下昨晚熬夜奮戰(zhàn)的結(jié)果。

受某個(gè)德國(guó)小朋友的委托,需要處理一個(gè)53M的xlsx文件。據(jù)這位小朋友介紹,如果直接用gdata包中的read.xls函數(shù)讀取會(huì)很慢,據(jù)說(shuō)是半年

。恰好我服務(wù)器上的gdata安裝總是不成功,自然也不能正常加載和使用read.xls文件。仔細(xì)考慮和查詢,發(fā)現(xiàn)xlsx文件實(shí)際上是壓縮的xml文件。

對(duì)于這一點(diǎn)在MicrosoftExcel的英文維基百科寫的還是比較清楚的(遇到問題一定要先去調(diào)查清楚,不要盲目的喊不知道)。這里附上MicrosoftExcel的wiki首頁(yè):http://en.wikipedia.org/wiki/Microsoft_Excel



從wiki的截圖我們可以看到,Microsoft Excel2007以前的版本都是用的二進(jìn)制文件(以xls結(jié)尾)作為主要的excel文件。而Microsoft Excel2007則采用的是Office Open XML文件作為主要文件格式。Office OpenXML是基于XML文件格式的XML擴(kuò)展文件,這個(gè)文件格式增在Excel2002中首次引入。PS:我沒有見過(guò)2002這個(gè)版本,這個(gè)版本比Excel2003還古老,那時(shí)候我還只會(huì)玩熱血傳奇。

所以綜上考慮,我可以用XML格式的讀取方式來(lái)讀取xlsx文件了。

1、解壓xlsx文件。

以下命令在bash shell中執(zhí)行:

[conda@mu01 Maggy]$ du -h Global_Terrorism.xlsx
53M    Global_Terrorism.xlsx

53M的xlsx文件,不知道解壓后會(huì)多大。

以下命令在R中運(yùn)行:
unzip("Global_Terrorism.xlsx")
使用這個(gè)命令,我們就把xlsx解壓成了xml格式了。解壓這個(gè)54M的文件,我們花了3.235s。

以下命令在bash shell中執(zhí)行:

[conda@mu01 test]$ du -h *
4.0K   [Content_Types].xml
12K    docProps
53M    Global_Terrorism.xlsx
8.0K   _rels
314M    xl
別看這個(gè)文件中有54M,解壓后出現(xiàn)了一個(gè)314M的worksheets文件夾。根據(jù)名字,我們就知道Excel中的sheet都存放在這個(gè)文件夾中了。
[conda@mu01 xl]$ du -h *
8.0K   _rels
39M    sharedStrings.xml
4.0K   styles.xml
12K    theme
4.0K   workbook.xml
276M   worksheets
這個(gè)文件夾中含有兩個(gè)比較大的文件,一個(gè)是39M的sharedStrings.xml和276Mworksheets文件夾,這個(gè)worksheets文件夾中有一個(gè)sheet1.xml文件。很明顯,這就是我們要真正讀取的文件,名字跟sheet命名一樣。

那么之前提到的sharedStrings.xml文件是什么?我們到后面慢慢看。

 

2、了解sheet1.xml

首先考慮查看一下sheet1.xml,一開始用的是less,但是發(fā)現(xiàn)很慢,可能是因?yàn)閘ess需要上下翻頁(yè),所以需要全部將文件讀取進(jìn)內(nèi)存,而more不用上下翻頁(yè),只需要向下翻頁(yè)就可以。所以考慮用more來(lái)查看文件。

 





上面兩張圖是在moresheet1.xml時(shí)候的截圖。 

首先我們來(lái)看第一張圖,這張圖里面我們可以看到第一行是:

 



這是xml文件的序言,按照wiki的說(shuō)明:每個(gè)XML文檔都由XML序言開始,在前面的代碼中的第一行就是XML序言。這一行代碼會(huì)告訴解析器或?yàn)g覽器這個(gè)文件應(yīng)該按照XML規(guī)則進(jìn)行解析。

接下來(lái)我們?cè)賮?lái)看第二行,實(shí)際上這個(gè)文件只有兩行,都沒有一個(gè)正確的文件結(jié)尾,以至于我在用readLines讀取的時(shí)候老是警告我說(shuō)沒有一個(gè)正確的文件結(jié)尾。一個(gè)300多兆的文件全部信息幾乎都集中在第二行。

我們來(lái)具體看下第二行說(shuō)了些什么:



這里我們可以看到這個(gè)worksheet節(jié)點(diǎn)定義了很多xmlns,xmlns其實(shí)是xmlnamespace的縮寫。用它來(lái)定義xml的命名空間。xml命名空間的wiki是這樣說(shuō)的:

XML文檔可能包括來(lái)自多個(gè)XML詞匯表的元素或?qū)傩裕绻恳粋€(gè)詞匯表指派一個(gè)命名空間,那么相同名字的元素或?qū)傩灾g的名稱沖突就可以解決。舉一個(gè)簡(jiǎn)單的例子來(lái)說(shuō),在一個(gè)訂單的XML文檔中需要引用到客戶和所購(gòu)買的產(chǎn)品,customer元素和product元素可能都有一個(gè)叫做id的子元素。這時(shí)候要引用id元素會(huì)造成名稱沖突,但是如果將兩個(gè)id元素放到不同的命名空間中就會(huì)解決這個(gè)問題。

命名空間使用元素的屬性來(lái)聲明,比如:

xmlns:xhtml="http://www.w3.org/1999/xhtml"

其中:

命名空間的聲明就是將一個(gè)前綴與一個(gè)URI關(guān)聯(lián)起來(lái)。

聲明命名空間時(shí),可以為命名空間定義前綴(見前例)。為命名空間定義前綴,而不直接使用命名空間的URI是因?yàn)閁RI為了唯一通常會(huì)很長(zhǎng),直接使用URI不但造成書寫和閱讀的不便,還會(huì)擾亂XML的語(yǔ)法。聲明命名空間時(shí),也可以不定義前綴。如:

xmlns="http://www.w3.org/1999/xhtml"

未定義前綴的命名空間被用作缺省的命名空間。

具體的定義大家可以自行查看wiki的xml命名空間頁(yè):http://zh.wikipedia.org/wiki/XML命名空間

接下來(lái)我們看到:

 



這里是一些配置信息,不足重要,我們接著看:



這里是cols節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)定義了很多col子節(jié)點(diǎn)。這里使用來(lái)說(shuō)明每一列的信息的。

再往下看:



在cols節(jié)點(diǎn)結(jié)束后,開始了,sheetData節(jié)點(diǎn)。這個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)以開始,很明顯,這里開始一行一行的定義數(shù)據(jù)了。

里面,我們可以看到實(shí)際上是指的每一個(gè)單元格,單詞cell???我也不清楚。然后是這個(gè)單元格的值。r="A1"是說(shuō)的這個(gè)單元格實(shí)際上是A1單元格,這個(gè)跟我們的Excel文檔能聯(lián)系起來(lái)。

下面是重點(diǎn):

 

 

 

這兩個(gè)節(jié)點(diǎn),他們有什么區(qū)別呢?第一個(gè)是A5格的,他的值是197001000002,但是K5格的值不是176。這里我們可以看到K5格的定義中有一個(gè)t="s",這里的意思是說(shuō)這個(gè)單元格的值在sharedStrings.xml里面,具體是sharedStrings.xml里面的哪一個(gè)?是sharedStrings.xml里面的第176個(gè)值。

 

3、解析xml

不多說(shuō),直接上代碼:

library(XML)

cat("Parsing sheet1 ... ... \n")
docSheet1 = xmlParse("xl/worksheets/sheet1.xml")
nodeRowC = getNodeSet(docSheet1,"http://a:row/a:c","a")
cat("Parsing sharedString\n")
docShareString = xmlParse("xl/sharedStrings.xml")
shareNode = getNodeSet(docShareString,"http://b:si/b:t","b")
#shareNode = shareNode[1:1000]
shareValue = unlist(lapply(shareNode,FUN=function(string)
{
  xmlValue(string)
}))
#nodeRowC = nodeRowC[1:1000]
cat("Parsing sheet1 to generating label ... ... \n")
startTime = Sys.time()
res = sapply(nodeRowC,FUN=function(string)
  {
  label = xmlGetAttr(string,name="r")
  value = xmlValue(string)
  shareIs = xmlGetAttr(string,name="t")
  if(is.null(shareIs))
  {
   return(c(label,value))
  }
  if(as.character(shareIs) == "s")
  {
    value =shareValue[as.numeric(value)+1]
  }
  return(c(label,value))
})
print (Sys.time() - startTime)

以下是代碼的顯示信息:

Parsing sheet1 ... ...
Parsing sharedString
Parsing sheet1 to generating label ... ...
Time difference of 36.39938 mins
在這里我們可以看到解析這個(gè)文件,我們花了大概36分鐘,相比讀取csv文件的秒速,這是幾個(gè)數(shù)量級(jí)的差別。

接下是重點(diǎn):

nodeRowC = getNodeSet(docSheet1,"http://a:row/a:c","a")

這個(gè)代碼是重點(diǎn)中的重點(diǎn)。最開始準(zhǔn)備用getNodeSet(docSheet1,"http://row/c")來(lái)解析。但是無(wú)論如何也找不到節(jié)點(diǎn)。開始懷疑是不是根節(jié)點(diǎn)的問題,于是在第二行前后都加上了和。發(fā)現(xiàn)還是不能解析正確。這樣就排除了是根節(jié)點(diǎn)的問題。最終確定是namespace命名空間的問題。

這里的a:row的意思是a命名空間。關(guān)于具體命名空間的信息,等碼完論文后我再來(lái)仔細(xì)學(xué)習(xí)下。今天就到此為止了。

 


  

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Excel有密碼保護(hù)無(wú)法編輯怎么辦?教你幾步去除密碼
關(guān)于Excel被保護(hù)的工作表忘記密碼的強(qiáng)制解除辦法
excel表格打開設(shè)置密碼了undefined可是現(xiàn)在忘了密碼怎么辦
Excel工作表保護(hù)密碼忘了?
純Java的方式讀取excel2007
Excel揭秘10:小心!Excel的保護(hù)工作表/工作簿密碼很容易破解
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服