从Linux中的Excel数据透视表电子表格中提取数据

时间:2010-12-13 22:06:27

标签: python linux excel csv

我有一个基于数据透视表的Excel电子表格,该数据表定期更新(每月)并上传到我的服务器(由一组非常犹豫改变输出中的任何内容生成)。我希望能够编写一个我可以通过cron job运行的脚本来处理并将数据从pivot表加载到我的数据库中。

但是,我无法弄清楚如何获取基础数据而无需手动进入Windows,在Excel中打开文件,双击总计单元格,获取包含填充的所有原始数据的新工作表那个单元格,并将该表格保存为csv,然后我可以通过某种语言(在我的案例中为python)加载到我的数据库中。看起来他们应该是一些可编写脚本的方法来提取底层数据。

我只有linux机器(在VM中运行Windows / office;但我更喜欢不涉及Windows的解决方案)。我熟悉xls2csv(它不访问原始数据)和使用python-unoconv之类的工具来编译python中的openoffice文档。但是,即使手动使用openoffice,我也看不到获取底层数据的方法。

编辑:花了好几个小时没有取得任何进展(在发布之前),我没有开始通过unoconv将其转换为ODS并且可能能够使用python-odf的东西来制作一些提取最后一张(称为'DPCache')。

所以现在问题是将ODS中的表格转换为CSV格式;这对我来说不应该太难理解(尽管非常感谢帮助)。

2 个答案:

答案 0 :(得分:1)

你试过xlrd吗?另请参阅python-excel website提供的教程。

就是这么简单:

>>> import xlrd
>>> book = xlrd.open_workbook('pivot_table_demo.xls')
>>> sheet = book.sheet_by_name('Summary')
>>> for row_index in xrange(sheet.nrows):
...     print sheet.row_values(row_index)
...
[u'Sum of sales', u'qtr', '', '', '', '']
[u'person', 1.0, 2.0, 3.0, 4.0, u'Grand Total']
[u'dick', 100.0, 99.0, 95.0, 90.0, 384.0]
[u'harriet', 100.0, 110.0, 121.0, 133.1, 464.1]
[u'tom', 100.0, 101.0, 102.0, 103.0, 406.0]
[u'Grand Total', 300.0, 310.0, 318.0, 326.1, 1254.1]
>>>

答案 1 :(得分:0)

我过去常常遇到同样的问题。您可以通过解压缩xlsx并读取/解释xml文件来解决。更重要的两个文件就是这些。

  • XL / pivotCache / pivotCacheDefinition1.xml
  • XL / pivotCache / pivotCacheRecords1.xml

第一个,拥有pivotCacheRecords1.xml中原始数据的关系,你需要通过索引号访问,我的意思是,在pivotCacheRecords1.xml中每个具有标记{{1}的列您需要通过标记<x>的索引号获取pivotCacheDefinition1.xml中的数据,为了更好地理解,您需要查看xml文件。

<强> pivotCacheDefinition1.xml

<x>

<强> pivotCacheRecords1.xml

    <?xml version="1.0" encoding="UTF-8"?>
<pivotCacheDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1" refreshedBy="ADNLatam" refreshedDate="42972.64919178241" createdVersion="5" refreshedVersion="6" recordCount="1923161">
   <cacheSource type="external" connectionId="1" />
   <cacheFields count="26">
      <cacheField name="C - Cadenas" numFmtId="0" sqlType="-9">
         <sharedItems count="3">
            <s v="superA" />
            <s v="superB" />
            <s v="superC" u="1" />
         </sharedItems>
      </cacheField>
      <cacheField name="C - Locales" numFmtId="0" sqlType="-9"><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
         <sharedItems count="80">
            <s v="Itaugua" />
            <s v="Denis Roa" />
            <s v="Total" />
            <s v="Los Laureles" />
            <s v="CDE" />
            <s v="S6 Fdo." />
            <s v="Central" u="1" />
            <s v="Unicompra" u="1" />
            <s v="San Lorenzo Centro" u="1" />
         </sharedItems>
      </cacheField>
   </cacheFields>
</pivotCacheDefinition>
</xml>

请参阅CacheRecords1标记中的<pivotCacheRecords xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" count="246209"> <r> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <s v="PAÐAL &quot;PAMPERS&quot; BABYSAN REGULAR GDE 9UN"/> #Z - Sku / Descripcion <s v="07501006720341"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <n v="1"/> <n v="11990"/> <n v="2.3199999999999998"/> <n v="10900"/> <n v="11990"/> <n v="1"/> <d v="2012-02-03T00:00:00"/> <x v="0"/> <x v="0"/> <n v="3"/> <n v="6"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> <x v="0"/> </r> 是CacheDefinition1中<x>标记的关系,现在如果你理解了这一点,那么制作一个dict在迭代中使用它并不是很困难。记录。

<s>

我们最终得到了这个词。

      definitions = '/tmp/scantrack_tmp/xl/pivotCache/pivotCacheDefinition1.xml'
      defdict = {}
      columnas = []
      e = xml.etree.ElementTree.parse(definitions).getroot()
      for fields in e.findall('{http://schemas.openxmlformats.org/spreadsheetml/2006/main}cacheFields'):
          for cidx, field in enumerate(fields.getchildren()):
              columna = field.attrib.get('name')
              defdict[cidx] = []
              columnas.append(columna)
              for value in field.getchildren()[0].getchildren():
                  tagname = value.tag
                  defdict[cidx].append(value.attrib.get('v', 0))

然后,当标签为{ 0: ['supera', 'superb', u'superc'], 1: ['Terminal', 'CDE', 'Brasilia', ] 3: ['PANTENE', 'DOVE'] ... }

时,你所有的todo都会迭代CacheRecords1并将列的索引与defdict中的键匹配
<x>

然后你可以将dfdata放在数据帧中

  dfdata = []


  bdata = '/tmp/scantrack_tmp/xl/pivotCache/pivotCacheRecords1.xml'

  for event, elem in xml.etree.ElementTree.iterparse(bdata, events=('start', 'end')):
    if elem.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}r' and event == 'start':
       tmpdata = []
       for cidx, valueobj in enumerate(elem.getchildren()):
           tagname = valueobj.tag
           vattrib = valueobj.attrib.get('v')
           rdata = vattrib
           if tagname == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}x':
                try:
                  rdata = defdict[cidx][int(vattrib)]
                except:
                  logging.error('this it not should happen index cidx = {} vattrib = {} defaultidcts = {} tmpdata for the time = {} xml raw {}'.format(
                                                                                                                                                cidx, vattrib, defdict, tmpdata,
                                                                                                                                                xml.etree.ElementTree.tostring(elem, encoding='utf8', method='xml')
                                                                                                                                                ))
           tmpdata.append(rdata)
       if tmpdata:
           dfdata.append(tmpdata)
       elem.clear()

其余的都是历史,我希望这会对你有所帮助。

快乐编码!!!