Используя панд и xlrd вместе. Игнорирование отсутствия / наличия заголовков столбцов - PullRequest
0 голосов
/ 02 сентября 2018

Я надеюсь, что вы можете помочь мне - я уверен, что это небольшая вещь, чтобы исправить, когда кто-то знает, как.

В моей мастерской ни я, ни мои коллеги не могут вносить изменения «найти и заменить все» через интерфейс нашей базы данных. Босс просто лишает нас такого уровня доступа. Если нам нужно внести изменения в десятки или, возможно, сотни записей, все это должно быть сделано путем копирования и вставки или аналогичными способами. Сумасшествие.

Я пытаюсь обойти это с помощью Python 2 и, в частности, таких библиотек, как Pandas, pyautogui и xlrd.

Я исследовал потоки Serval StackOverflow и до сих пор сумел написать некоторый код, который хорошо работает при чтении данного файла XL. В процессе работы это будет файл, экспортированный из найденного набора данных в интерфейсе GUI базы данных, и будет просто один столбец «Номера статей» для предметов в компьютерной мастерской. Это всегда будет иметь заголовок столбца Excel. * 1007 например *

ANR
51234
34567
12345
...

Все номера записей состоят из 5 цифр. У нас также есть средства сканирования элементов с помощью ИК-сканера в приложение «Рабочий процесс» на iPad, которое у нас есть, и автоматическое создание файла XL из этого списка отсканированных элементов.

Файл XL здесь может выглядеть примерно так:

56788
12345
89012
...

Отличается тем, что заголовок столбца отсутствует. Все XL-файлы имеют свои «якорные» данные в ячейке A1 на «Sheet1», и снова будет использоваться только один столбец. Никаких лишних сложностей здесь!

В любом случае, вот сценарий. Когда он полностью заработает, системные аргументы будут ему предоставлены. А пока давайте представим, что нам нужно изменить записи, чтобы их значение «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, если ему не хватает его в первую очередь? - то есть файлы XL, которые поступают с ИК-сканера и из приложения «Рабочий процесс» на iPad?

Спасибо, ребята!

UPDATE

Я пытался, как предложил Патрик, реализовать некоторый код, чтобы проверить, имеет ли ячейка "A1" заголовок или нет. Частичный успех. Я могу поместить «ANR» в ячейку A1, если она отсутствует, но я теряю то, что было в первую очередь.

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.

Я нашел этот новый блок кода на записи в существующую книгу с использованием xlwt . В этом случае автор фактически использовал openpyxl.

1 Ответ

0 голосов
/ 02 сентября 2018

Кажется, я исправил это для себя.

Все еще немного грязно, но, кажется, работает. Добавлено условие if / else для проверки значения ячейки A1 и принятия соответствующих мер. Нашел большую часть кода для этого в , как добавить данные, используя python openpyxl, чтобы превзойти файл из указанной строки? - используя предложение для openpyxl

import pyperclip
import xlrd
import pyautogui
import string
import re
import os
import pandas as pd
import xlwt
from openpyxl import Workbook, load_workbook
from xlutils.copy import copy


field = "RAM"
value = "2 GB"
myFile = "/Users/me/testSerials.xlsx"
df = pd.read_excel(myFile)


myRegex = "^[0-9]{5}$"

# 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:
    headers = ['ANR']
    workbook_name = 'myFile'
    wb = Workbook()
    page = wb.active
    # page.title = 'companies'
    page.append(headers)  # write the headers to the first line

    workbook = xlrd.open_workbook(workbook_name)
    sheet = workbook.sheet_by_index(0)
    data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]

    for records in data:
        page.append(records)

        wb.save(filename=workbook_name)

        #then load the data all over again, this time with inserted header
        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
    cellValue = cellValue[:-2]
    # cellValue = cellValue.translate(None, ".0")
    cellValue = cellValue.translate(None, string.letters)

    # making sure any valid ANRs get through
    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)


# ref - https://stackoverflow.com/questions/48942743/python-pandas-to-remove-rows-in-excel
df = pd.read_excel(myFile)

print df


for i in deDuped:
    #pyautogui code is run here...

    #if all goes to plan update the XL file
        df = df[~df['ANR'].astype(str).str.startswith(i)]

        df.to_excel(myFile, index=False)
...