在python中使用csv模块写入特定单元格

esyap4oy  于 2022-12-25  发布在  Python
关注(0)|答案(5)|浏览(213)

我必须将值写入csv文件中的特定单元格(比如第8个单元格),我可以看到有一个csvwriter.writerow(row)方法可以写入整行,但没有看到任何方法可以将值写入特定单元格。

uubf1zoe

uubf1zoe1#

csv module提供了读取和写入csv文件的工具,但不允许就地修改特定单元格
即使是您在问题中强调的csvwriter.writerow(row)方法也不允许您识别和覆盖特定的行,而是将row参数写入写入写入器的file对象,实际上它只是在与写入器关联的csv文件中附加一行。
尽管如此,不要放弃使用csv module,它使用起来很简单,而且通过提供的原语,您可以相对容易地实现您正在寻找的更高级功能。
例如,看一下下面的csv文件:

1,2,3,four,5
1,2,3,four,5
1,2,3,four,5

单词four在第3列(第4列,但行只是列表,因此索引是基于零的),这可以通过以下程序容易地更新为包含数字4

import csv
in_file = open("d:/in.csv", "rb")
reader = csv.reader(in_file)
out_file = open("d:/out.csv", "wb")
writer = csv.writer(out_file)
for row in reader:
    row[3] = 4
    writer.writerow(row)
in_file.close()    
out_file.close()

导致输出:

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5

诚然,创建一些允许识别和更新特定行和列的通用函数需要做更多的工作,但这并不像在Python中操作csv文件那样,只是操作一系列列表。

rqcrx0a6

rqcrx0a62#

假设您有一个名为mylist.csv的csv文件,其中包含以下行:

a, b, c, d

e, f, g, h

i, j, k, l

如果你想把“h”修改成“X”,可以使用下面代码,需要导入csv模块:

f = open('mylist.csv', 'r')
    reader = csv.reader(f)
    mylist = list(reader)
    f.close()
    mylist[1][3] = 'X'
    my_new_list = open('mylist.csv', 'w', newline = '')
    csv_writer = csv.writer(my_new_list)
    csv_writer.writerows(mylist)
    my_new_list.close()

如果要修改每行的特定列,只需添加for循环进行迭代。

6ovsh4lw

6ovsh4lw3#

我同意,这很烦人。我最终子类化了csv.DictReader。这允许基于单元格的查找编辑和转储。我在activestate上发布了代码:In place csv lookup, manipulation and export

import csv, collections, copy

"""
# CSV TEST FILE 'test.csv'

TBLID,DATETIME,VAL
C1,01:01:2011:00:01:23,5
C2,01:01:2012:00:01:23,8
C3,01:01:2013:00:01:23,4
C4,01:01:2011:01:01:23,9
C5,01:01:2011:02:01:23,1
C6,01:01:2011:03:01:23,5
C7,01:01:2011:00:01:23,6
C8,01:01:2011:00:21:23,8
C9,01:01:2011:12:01:23,1

#usage (saving this cose as CustomDictReader.py)

>>> import CustomDictReader
>>> import pprint
>>> test = CustomDictReader.CSVRW()
>>> success, thedict = test.createCsvDict('TBLID',',',None,'test.csv')
>>> pprint.pprint(dict(thedict))
{'C1': OrderedDict([('TBLID', 'C1'), ('DATETIME', '01:01:2011:00:01:23'), ('VAL', '5')]),
 'C2': OrderedDict([('TBLID', 'C2'), ('DATETIME', '01:01:2012:00:01:23'), ('VAL', '8')]),
 'C3': OrderedDict([('TBLID', 'C3'), ('DATETIME', '01:01:2013:00:01:23'), ('VAL', '4')]),
 'C4': OrderedDict([('TBLID', 'C4'), ('DATETIME', '01:01:2011:01:01:23'), ('VAL', '9')]),
 'C5': OrderedDict([('TBLID', 'C5'), ('DATETIME', '01:01:2011:02:01:23'), ('VAL', '1')]),
 'C6': OrderedDict([('TBLID', 'C6'), ('DATETIME', '01:01:2011:03:01:23'), ('VAL', '5')]),
 'C7': OrderedDict([('TBLID', 'C7'), ('DATETIME', '01:01:2011:00:01:23'), ('VAL', '6')]),
 'C8': OrderedDict([('TBLID', 'C8'), ('DATETIME', '01:01:2011:00:21:23'), ('VAL', '8')]),
 'C9': OrderedDict([('TBLID', 'C9'), ('DATETIME', '01:01:2011:12:01:23'), ('VAL', '1')])}
>>> thedict.keys()
['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9']
>>> thedict['C2']['VAL'] = "BOB"
>>> pprint.pprint(dict(thedict))
{'C1': OrderedDict([('TBLID', 'C1'), ('DATETIME', '01:01:2011:00:01:23'), ('VAL', '5')]),
 'C2': OrderedDict([('TBLID', 'C2'), ('DATETIME', '01:01:2012:00:01:23'), ('VAL', 'BOB')]),
 'C3': OrderedDict([('TBLID', 'C3'), ('DATETIME', '01:01:2013:00:01:23'), ('VAL', '4')]),
 'C4': OrderedDict([('TBLID', 'C4'), ('DATETIME', '01:01:2011:01:01:23'), ('VAL', '9')]),
 'C5': OrderedDict([('TBLID', 'C5'), ('DATETIME', '01:01:2011:02:01:23'), ('VAL', '1')]),
 'C6': OrderedDict([('TBLID', 'C6'), ('DATETIME', '01:01:2011:03:01:23'), ('VAL', '5')]),
 'C7': OrderedDict([('TBLID', 'C7'), ('DATETIME', '01:01:2011:00:01:23'), ('VAL', '6')]),
 'C8': OrderedDict([('TBLID', 'C8'), ('DATETIME', '01:01:2011:00:21:23'), ('VAL', '8')]),
 'C9': OrderedDict([('TBLID', 'C9'), ('DATETIME', '01:01:2011:12:01:23'), ('VAL', '1')])}
>>> test.updateCsvDict(thedict)
>>> test.createCsv('wb')
"""

class CustomDictReader(csv.DictReader):
    """
        override the next() function and  use an
        ordered dict in order to preserve writing back
        into the file
    """

    def __init__(self, f, fieldnames = None, restkey = None, restval = None, dialect ="excel", *args, **kwds):
        csv.DictReader.__init__(self, f, fieldnames = None, restkey = None, restval = None, dialect = "excel", *args, **kwds)

    def next(self):
        if self.line_num == 0:
            # Used only for its side effect.
            self.fieldnames
        row = self.reader.next()
        self.line_num = self.reader.line_num

        # unlike the basic reader, we prefer not to return blanks,
        # because we will typically wind up with a dict full of None
        # values
        while row == []:
            row = self.reader.next()
        d = collections.OrderedDict(zip(self.fieldnames, row))

        lf = len(self.fieldnames)
        lr = len(row)
        if lf < lr:
            d[self.restkey] = row[lf:]
        elif lf > lr:
            for key in self.fieldnames[lr:]:
                d[key] = self.restval
        return d

class CSVRW(object):

    def __init__(self):
        self.file_name = ""
        self.csv_delim = ""
        self.csv_dict  = collections.OrderedDict()

    def setCsvFileName(self, name):
        """
            @brief stores csv file name
            @param name- the file name
        """
        self.file_name = name

    def getCsvFileName(self):
        """
            @brief getter
            @return returns the file name
        """
        return self.file_name

    def getCsvDict(self):
        """
            @brief getter
            @return returns a deep copy of the csv as a dictionary
        """
        return copy.deepcopy(self.csv_dict)

    def clearCsvDict(self):
        """
            @brief resets the dictionary
        """
        self.csv_dict = collections.OrderedDict()

    def updateCsvDict(self, newCsvDict):
        """
            creates a deep copy of the dict passed in and
            sets it to the member one
        """
        self.csv_dict = copy.deepcopy(newCsvDict)

    def createCsvDict(self,dictKey, delim, handle = None, name = None, readMode = 'rb', **kwargs):
        """
            @brief create a dict from a csv file where:
                the top level keys are the first line in the dict, overrideable w/ **kwargs
                each row is a dict
                each row can be accessed by the value stored in the column associated w/ dictKey

                that is to say, if you want to index into your csv file based on the contents of the
                third column, pass the name of that col in as 'dictKey'

            @param dictKey  - row key whose value will act as an index
            @param delim    - csv file deliminator
            @param handle   - file handle (leave as None if you wish to pass in a file name)
            @param name     - file name   (leave as None if you wish to pass in a file handle)
            @param readMode - 'r' || 'rb'
            @param **kwargs - additional args allowed by the csv module
            @return bool    - SUCCESS|FAIL
        """
        self.csv_delim = delim
        try:
            if isinstance(handle, file):
                self.setCsvFileName(handle.name)
                reader = CustomDictReader(handle, delim, **kwargs)
            else:
                if None == name:
                    name = self.getCsvFileName()
                else:
                    self.setCsvFileName(name)
                reader = CustomDictReader(open(name, readMode), delim, **kwargs)
            for row in reader:
                self.csv_dict[row[dictKey]] = row
            return True, self.getCsvDict()
        except IOError:
            return False, 'Error opening file'

    def createCsv(self, writeMode, outFileName = None, delim = None):
        """
            @brief create a csv from self.csv_dict
            @param writeMode   - 'w' || 'wb'
            @param outFileName - file name || file handle
            @param delim       - csv deliminator
            @return none
        """
        if None == outFileName:
            outFileName = self.file_name
        if None == delim:
            delim = self.csv_delim
        with open(outFileName, writeMode) as fout:
            for key in self.csv_dict.values():
                fout.write(delim.join(key.keys()) + '\n')
                break
            for key in self.csv_dict.values():
                fout.write(delim.join(key.values()) + '\n')
c3frrgcw

c3frrgcw4#

使用xlwt模块,可以对电子表格进行多种操作,可以写入Excel中的特定单元格。

import xlwt 

from xlwt import Workbook
wb = Workbook() 
sheet1 = wb.add_sheet('Sheet 1') 
sheet1.write(1, 0, 'stack') 
sheet1.write(0, 1, 'overflow') 
wb.save('stackoverflow.xls')
06odsfpq

06odsfpq5#

如果你真的需要在一个.csv文件中写一个特定的单元格,并且你不能避免使用这个模块,有一个硬编码的方法来完成它。
假设你想在单元格H3中输入一些东西:

with open("your_csv_file_name.csv","w",newline="") as openfile:
    your_csv_file_name = csv.writer(openfile)

    value_for_cell_h3 = "X"

    list_of_blank_columns_and_h3value = ["","","","","","","",value_for_cell_h3]   
    #Columns from A to G will be blank

    your_csv_file_name.writerow("")   #Row 1 will be blank
    your_csv_file_name.writerow("")   #Row 2 will be blank

    your_csv_file_name.writerow(list_of_blank_columns_and_h3value)
    #The "X" will be in the H3 cell

相关问题