0

Excel シートの特定の日付の値を変更するスクリプトを作成しました。を使用して新しい Excel ファイルを作成するcopyと、日付の年の部分を除いてすべてが正しくコピーされます。たとえば、2012 年 4 月 5 日から 2008 年 4 月 5 日になります。すべての日付は 4 年前にさかのぼるようです。コードは次のとおりです。

def exceledit():
#open excel sheet                                                           
import xlrd, xlwt, xlutils
import datetime
from xlutils.copy import copy
print 'Opening excel sheet...'
book = xlrd.open_workbook('test.xls', on_demand=True, formatting_info=True)
print 'Creating and editing new excel sheet...'
wbook = copy(book)
print 'Done creating new excel sheet'

sh = book.sheet_by_index(0)
#iterate through dates in excel sheet                                       
for colnum in range(sh.ncols):
    date = sh.cell_value(3, colnum+4)
    #if xlrd finds a date                                                   
    if date:
        #grab date data                                                     
        year, month, day, hour, minute, second =  xlrd.xldate_as_tuple(date\
    , book.datemode)
        #if dates are within the month currently being edited               
        if month == 04:
            #format excel date information to work with parkh dict          
            format =  str(month) + "/" + str(day) + "/" + str(year)        
            print 'Editing ' + format
            #clear cells to eliminate old information                       
            wbook.get_sheet(0).write(6, colnum+6, "")
            wbook.get_sheet(0).write(5, colnum+6, "")
    wbook.get_sheet(0).write(7, colnum+6, "")
            #iterate through hour segments for that day                     
            for x in parkh[format]:
                #if regular hours, insert in "HOURS" row                    
                if x[0] == 'Park Hours':
                    wbook.get_sheet(0).write(6, colnum+6, x[1])
                #if extra magic hours, insert in respective row             
                if x[0] == 'Extra Magic Hours':
                    #insert in morning row                                  
                    if int(x[1][0:1]) in range(2,9):
                        wbook.get_sheet(0).write(5, colnum+6, x[1])
                    #insert in evening row                                  
                    else:
                        wbook.get_sheet(0).write(7, colnum+6, x[1])

        if month == 05:
            break

print 'Done editing. Now saving...'
wbook.save('new.xls')
print 'new.xls saved'

なぜそれが年を変えるのでしょうか?他の場所で同じ問題を抱えている人を見たことがありません。

4

2 に答える 2

1

1904 日付システムを使用している入力 Excel ファイルがあることは明らかです。当面の問題は、xlutilsこれらのファイルを正しくコピーできないことです。幸いなことに、修正はワンライナーであり、コピーを行った後、スクリプトで自分で修正することもできます。

wbook = copy(book)
wbook.dates_1904 = book.datemode

xlwtこれは、使用中の日付モードを指定するレコードの書き込みをサポートするため、日付のコピーに機能します。

警告Worksheet.write() を使用してファイルに書き込む新しい日付値は正しく書き込まれません。残念ながら、変換時に設定がxlwt無視され、オブジェクトが Excel マジック フロートに変換されるためです。dates_1904datetime.datedatetime.datetime

Row.__excel_date_dtメソッドの本体全体を置き換える修正を書き、テストしました。すぐに新しいxlwtリポジトリにgithubコミットされます。それまでの間、差し迫った必要がある場合のコードは次のとおりです。

def __excel_date_dt(self, date):
    adj = False
    if isinstance(date, dt.date):
        if self.__parent_wb.dates_1904:
            epoch_tuple = (1904, 1, 1)
        else:
            epoch_tuple = (1899, 12, 31)
            adj = True
        if isinstance(date, dt.datetime):
            epoch = dt.datetime(*epoch_tuple)
        else:
            epoch = dt.date(*epoch_tuple)
    else: # it's a datetime.time instance
        epoch = dt.datetime(1900, 1, 1)            
        date = dt.datetime.combine(epoch, date)
    delta = date - epoch
    xldate = delta.days + delta.seconds / 86400.0
    # Add a day for Excel's missing leap day in 1900
    if adj and xldate > 59:
        xldate += 1
    return xldate    

警告Excel でファイルを開き、1904 構成項目のチェックを外してファイルを保存することにより、ファイルを 1900 システムに変換しようとしていますが、うまくいきません

正しく動作しているように見えるのは次のとおりです。

  • Excel でファイルを開き、名前を付けて保存しますXML Spreadsheet 2003 (*.xml)... この形式は、日付をテキスト形式で記録します。 1999-12-31T23:59:59.999


  • <Date1904/>XML ファイルをテキスト エディタで開き、 ... yes, the XML is human- reading straight out of the box ...という行を見つけて削除し、xml ファイルを保存します。

  • 変更された XML ファイルを Excel で開くと、すべてのデータと書式設定
    が保持されます。唯一の違いは、厄介な
    1904 ボックスがチェックされていないことです。その後、XLSファイルとして保存できます

于 2012-04-08T12:16:24.770 に答える
0

I have experienced this with Excel workbooks, not even using Python. When the same file gets passed around between Windows and Mac, weird things can happen with the dates (though this is not typical). Excel for Windows defaults to the so-called "1900" date system, while Excel for Mac defaults to the "1904" date system. (These are the starting years for the respective systems.)

Though the xlrd documentation and source code strongly recommend you stick with the datemode value that is encoded in the workbook (as you have done), I think it's worth a try explicitly giving the "other" mode to xldate_as_tuple to see if it fixes your problem:

year, month, day, hour, minute, second = xlrd.xldate_as_tuple(date,
    1 - book.datemode)

datemode will be 0 for 1900 mode, 1 for 1904 mode; 1 - datemode flips this.

Incidentally, you can break lines without the backslash as long as you are breaking after a comma in a parenthesized expression.

于 2012-04-05T22:56:09.803 に答える