重写数据到使用Python现有工作簿(Overwriting data to an existing

2019-10-29 08:26发布

我是新来的Python和我可以使用一些帮助的一个项目工作。 所以我想以比较股票数据修改现有的Excel工作簿。 幸运的是,有是获取我需要的所有数据的节目在线和我有成功的能提取数据,并将数据写入到一个新的Excel文件。 然而,我们的目标是提取数据,并把它变成一个现有的Excel文件。 此外,我需要覆盖现有文件中的单元格值。 我相信xlwings是能够做到这一点,我想我的代码是在正确的轨道上,但是我遇到了一个意外的错误。 我得到的错误是:

TypeError: Objects of type 'Period' can not be converted to a COM VARIANT (but obtaining the buffer() of this object could)

我想知道是否有人知道为什么这个错误想出了? 此外,没有人知道如何解决它? 它是可以解决的? 是我的代码错了吗? 任何帮助或指导表示赞赏。 谢谢。

import good_morning as gm
import pandas as pd
import xlwings as xw

#import income statement, balance sheet, and cash flow of AAPL
fd = gm.FinancialsDownloader()
fd_frames = fd.download('AAPL')

#Creates a DataFrame for only the balance sheet
df1 = pd.DataFrame(list(fd_frames.values())[0])

#connects to workbook I want to modify 
wb = xw.Book(r'C:\Users\vince\Project\Spreadsheet.xlsm')

#sheet I would like to modify
sht = wb.sheets[1]

#modifies & overwrites values in my spreadsheet(this is where I get the type_error)
sht.range('M6').value = df1

数据类型

type(fd_frames)
>>> <class 'dict'>
fd_frames.values())[0].info()
>>> <class 'pandas.core.frame.DataFrame'> 
RangeIndex: 22 entries, 0 to 21 
Data columns (total 8 columns): 
parent_index 22 non-null int64 
title 22 non-null object 
2012 19 non-null float64 
2013 20 non-null float64 
2014 20 non-null float64 
2015 20 non-null float64 
2016 20 non-null float64 
2017 20 non-null float64 
dtypes: float64(6), int64(1), object(1) 
memory usage: 1.5+ KB

Answer 1:

评论 :你的快译通 pandas.DataFrame

使用从一个字典选择list(fd_frames.values())[0]并导致不可预测的结果。 显示词典的按键,然后选择一个你感兴趣的关闭使用这些按键,例如:

 print(fd_frames.keys())
 >>> dict_keys(['key_1', 'key_2', 'key_n']
 df_2 = fd_frames['key_2']

除了这一点,无论是在你的尺寸的pandas.DataFrame确实匹配M6:M30 = 25,只有820个值 的列 。 Therfore你要调整你的工作表区域至20行 。 写专栏2017年的工作表,例如:

wb['M6:M25'] = df_2['2017'].values

:我已经更新下面的代码接受numpy.ndarray也。


:......我们的目标是提取数据,并把它变成一个现有的Excel文件

更新工作簿工作表区域与列表值。
使用:OpenPyXL: 一个Python库进行读/写的Excel 2010 XLSX / XLSM文件

:观察列表值怎么也得安排!
PARAM值:表:* [第1行(COL1,...,科隆),...,第n行(COL1,...,科隆)]`

from openpyxl import Workbook, load_workbook

class UpdateWorkbook(object):
    def __init__(self, fname, worksheet=0):
        self.fname = fname
        self.wb = load_workbook(fname)
        self.ws = self.wb.worksheets[worksheet]

    def save(self):
        self.wb.save(self.fname)

    def __setitem__(self, _range, values):
        """
         Assign Values to a Worksheet Range
        :param _range:  String e.g ['M6:M30']
        :param values: List: [row 1(col1, ... ,coln), ..., row n(col1, ... ,coln)]
        :return: None
        """

        def _gen_value():
            for value in values:
                yield value

            if not isinstance(values, (list, numpy.ndarray)):
                raise ValueError('Values Type Error: Values have to be "list": values={}'.
                                  format(type(values)))
            if isinstance(values, numpy.ndarray) and values.ndim > 1:
                raise ValueError('Values Type Error: Values of Type numpy.ndarray must have ndim=1; values.ndim={}'.
                                  format(values.ndim))

        from openpyxl.utils import range_boundaries
        min_col, min_row, max_col, max_row = range_boundaries(_range)
        cols = ((max_col - min_col)+1)
        rows = ((max_row - min_row)+1)
        if cols * rows != len(values):
            raise ValueError('Number of List Values:{} does not match Range({}):{}'.
                             format(len(values), _range, cols * rows))

        value = _gen_value()
        for row_cells in self.ws.iter_rows(min_col=min_col, min_row=min_row,
                                           max_col=max_col, max_row=max_row):
            for cell in row_cells:
                cell.value = value.__next__()

用法

 wb = UpdateWorkbook(r'C:\Users\vince\Project\Spreadsheet.xlsx', worksheet=1) df_2 = fd_frames['key_2'] wb['M6:M25'] = df_2['2017'].values wb.save() 

经测试使用Python 3.4.2 - openpyxl:2.4.1 - LibreOffice的:4.3.3.2



Answer 2:

以下是我对其他协议栈探险做一个类似的过程:

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

... create your pandas dataframe df...

# Writing from pandas back to an existing EXCEL workbook
# Load workbook
wb = load_workbook(filename=target, read_only=False, keep_vba=True)
ws = wb['Sheet1']

# Overwrite Existing data in sheet with a dataframe.
rows = dataframe_to_rows(df, index=False, header=True)

for r_idx, row in enumerate(rows, 1):
    for c_idx, value in enumerate(row, 1):
         ws.cell(row=r_idx, column=c_idx, value=value)

# Save file
wb.save('outfile.xlsm')


文章来源: Overwriting data to an existing workbook using Python