1 需求描述
需要修改excel中的重复的字段,比如123, 123, fws. fws,这种
将这里面的字段修改成123A, 123B, fws1, fws2,这种。
2 核心算法
其中最为主要的是名字的命名规则。
问题描述如下
- 如果对于指定字段,出现了重复的值,先看是以数字结尾还是以字符结尾。
- 如果是以字符结尾,则给重复的值末尾添加从1开始的数字。
- 如果以数字结尾,则给重复的值末尾添加以A开始的字符。
- 其中字符如果超过了26个,就以AA, AB这种进行叠加,数字从1开始,每次增加1
示列
比如出现了123重复了28次, fda出现了11次
- 则给相同的123分别修改为
123A, 123B,123C … 123Z, 123AA, 123AB - 给将fda修改为
fda1, fad2, … fda10, fda11
约束条件
- 其中所有的字段的值只有数字和字母,并且不包含小数。
- 字段中值的个数 < 1 0 6 10^6 106
求解思路
将数字转化成26进制,只不过转化的时候需要将n / 26变成(n - 1) ./ 26就行了。
3. 整体流程
- 读入整张表格
- 按照给定字段属性进行排序
- 如果给定字段的相邻值之间相等则进行修改
- 根据不同的命名规则对相同的值进行修改
4. 代码实现
import xlrd
from xlutils.copy import copy
"""
1. 保证排序之后
2. 保证没有浮点数作为名字
3. 修改后会改变文件的字体的格式
"""
def readEx(fileName, sheetId, c) :
names = []
worksheet = xlrd.open_workbook(fileName)
sheet_names = worksheet.sheet_names()
# 返回sheet的name ['structure', 'data', 'Sheet1', '备注', '命运卡', '地图(废弃)']
print(sheet_names)
# 取第二个sheet页data
rsheet = worksheet.sheet_by_index(sheetId)
# row表示行
for row in rsheet.get_rows():
# 获取第c列
id_column = row[c]
id_value = id_column.value
names.append(str(id_value).split('.')[0])
return names
def write(fileName, names, c) :
worksheet = xlrd.open_workbook(fileName)
new_book = copy(worksheet)
sheet_names = worksheet.sheet_names()
# 返回sheet的name ['structure', 'data', 'Sheet1', '备注', '命运卡', '地图(废弃)']
print(sheet_names)
# 将name中的内容 写入新文件的第0列就行了
sheet = new_book.get_sheet(0)
for i in range(len(names)) :
sheet.write(i, c, names[i])
new_book.save('2.xls')
def getChar(n) : # 将n映射成字符串
# print('n = ' + str(n))
charList = ["A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U" ,"V", "W", "X", "Y", "Z"]
if n == 0: return "A"
ans = ""
while n != 0:
idx = int(n % 26)
ans += charList[idx - 1]
n = (int)((n - 1) / 26)
ans = ans[::-1]
return ans
def getNum(n) :
if n == 0: return "0"
ans = ""
while n != 0:
ans += str((n % 10))
n = (int)(n /10)
ans = ans[::-1]
return ans
def change(s, n) :
if s[-1].isdigit() : # 如果是数字,直接加上字符
s += getChar(n)
else :
s += getNum(n) # 如果是字符,直接加上数字
return s
def solve(list) :
cnt = 1 # 重复的数字是现在第几名了
for i in range(len(list) - 1):
if (list[i] == list[i + 1]):
list[i] = change(list[i], cnt)
cnt += 1
elif cnt != 1: # 最后一个需要处理的
list[i] = change(list[i], cnt)
cnt = 1
if cnt != 1:
list[-1] = change(list[-1], cnt)
return list
if __name__ == '__main__':
print("要替换的文件需与脚本同一目录")
fileName = input("输入文件名,加上扩展名字 ,比如1.xlsx:")
sheetId = input("输入第几个sheet, 从1开始计数字:")
sheetId = int(sheetId) - 1
c = input("输入需要修改的是第几列,从1开始计数 :")
c = int(c) - 1
names = readEx(fileName, sheetId, c)
names = solve(names)
write(fileName, names, c)
print("修改好的列放在了2.xlsx")
5. 注意事项
如果判断条件是和下一个比较修改本个
- 循环条件应该是n - 1终止
- 对于最后一个需要修改的值在出循环之后需要进行修改
- 计数过程中如果不相等且cnt == 1说明最后一个还没有进行修改,仍旧需要修改,并且重置cnt = 1
- cnt开始从1,这样更容易计数。