【发布时间】:2018-09-02 09:07:21
【问题描述】:
我希望你能帮助我 - 我确信它可能是一件小事,只要知道如何解决。
在我的工作室中,我和我的同事都无法通过我们数据库的前端进行“查找并替换所有”更改。老板只是拒绝我们这种级别的访问权限。如果我们需要对数十条甚至数百条记录进行更改,则必须全部通过复制粘贴或类似方式完成。疯狂。
我正在尝试使用 Python 2 来解决这个问题,特别是 Pandas、pyautogui 和 xlrd 等库。
我已经研究了多个 StackOverflow 线程,并且到目前为止已经设法编写了一些在读取给定 XL 文件时运行良好的代码。在生产中,这将是从数据库 GUI 前端中找到的数据集中导出的文件,并且将只是计算机车间中项目的单列“物品编号”。这将始终有一个 Excel 列标题。例如
ANR
51234
34567
12345
...
所有记录编号均为 5 位数字。 我们还可以使用 IR 扫描仪将物品扫描到我们拥有的 iPad 上的“工作流程”应用程序中,并自动从该扫描物品列表中制作一个 XL 文件。
此处的 XL 文件可能与此类似。
56788
12345
89012
...
不同之处在于没有列标题。所有 XL 文件的数据都“锚定”在“Sheet1”上的单元格 A1 中,并且将再次使用单列。这里没有不必要的复杂性!
无论如何,这是脚本。当它完全工作时,系统参数将被提供给它。现在,假设我们需要更改记录以使其“RAM”值从"2GB" 更改为"2 GB"。
import xlrd
import string
import re
import pandas as pd
field = "RAM"
value = "2 GB"
myFile = "/Users/me/folder/testArticles.xlsx"
df = pd.read_excel(myFile)
myRegex = "^[0-9]{5}$"
# data collection and putting into lists.
workbook = xlrd.open_workbook(myFile)
sheet = workbook.sheet_by_index(0)
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]
formatted = []
deDuped = []
# removing any possible XL headers, setting all values to strings
# that look like five-digit ints, apply a regex to be sure.
for i in data:
cellValue = str(i)
cellValue = cellValue.translate(None, '\'[u]\'')
# remove the decimal point
# Searching for the header will cause a database front-end problem.
cellValue = cellValue[:-2]
cellValue = cellValue.translate(None, string.letters)
# making sure only valid article numbers get through
# blank rows etc can take a hike
if len(cellValue) != 0:
if re.match(myRegex, cellValue):
formatted.append(cellValue)
# weeding out any possilbe dupes.
for i in formatted:
if i not in deDuped:
deDuped.append(i)
#main code block
for i in deDuped:
#lots going on here involving pyauotgui
#making sure of no error running searches, checking for warnings, moving/tabbing around DB front-end etc
#if all goes to plan
#removing that record number from the excel file and saving the change
#so that if we run the script again for the same XL file
#we don't needlessly update an already OK record again.
df = df[~df['ANR'].astype(str).str.startswith(i)]
df.to_excel(myFile, index=False)
我真正想知道的是如何运行脚本,以便“不关心”列标题的存在与否。
df = df[~df['ANR'].astype(str).str.startswith(i)]
似乎是这一切都挂起的代码行。我以不同的组合对该行进行了多次更改,但我的脚本总是崩溃。
如果列标题(在我的情况下为“ANR”)对于这种特定的“pandas”方法是必不可少的,是否有一种直接的方法可以将列标题插入到 XL 文件中,如果它首先缺少列标题- 即来自 IR 扫描仪和 iPad 上的“工作流程”应用程序的 XL 文件?
谢谢大家!
更新
我已经按照 Patrick 的建议尝试了一些代码来检查单元格“A1”是否有标题。部分成功。如果单元格 A1 丢失,我可以将“ANR”放入单元格,但我首先会丢失那里的任何内容。
import xlwt
from openpyxl import Workbook, load_workbook
from xlutils.copy import copy
import openpyxl
# data collection
workbook = xlrd.open_workbook(myFile)
sheet = workbook.sheet_by_index(0)
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]
cell_a1 = sheet.cell_value(rowx=0, colx=0)
if cell_a1 == "ANR":
print "has header"
else:
wb = openpyxl.load_workbook(filename= myFile)
ws = wb['Sheet1']
ws['A1'] = "ANE"
wb.save(myFile)
#re-open XL file again etc etc.
我在writing to existing workbook using xlwt 找到了这个新代码块。在这种情况下,贡献者实际上使用了 openpyxl。
【问题讨论】:
-
为什么不创建一个打开 xlsx 的准备步骤,检查
if not A1 == 'ANR':,如果是这样:插入一个单元格为A1,内容为'ANR',将所有其他单元格 1 向下推。现在您获得了相同格式的两个文件,可以轻松完成剩下的工作了吗? -
感谢您的提示。你是对的,这也许是解决问题的最直接的方法。
标签: python python-2.7 pandas xlrd