Topic: Richiesta di aiuto per utilizzo openpyxl  (Letto 60 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Walter

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
Richiesta di aiuto per utilizzo openpyxl
« il: Aprile 13, 2020, 18:14 »
Buon pomeriggio,
sono nuovo del forum e anche di Python. Non ho trovato dove presentarmi. Non c'è molto da dire: sono un tecnico che si occupa di acustica ambientale, architettonica, in edilizia e negli ambienti di lavoro. Cerco di utilizzare Python per alcune elaborazioni legate al mio mondo professionale. Ho bisogno di aiuto per manipolare un foglio excel; mi pare di aver capito che posso utilizzare openpyxl. Le cose che devo fare sono queste. La prima riga del file excel contiene i titoli delle righe. Devo creare una nuova colonna in cui scrivere "feriale" o "festivo" in basa alla data di calendario riportata in una colonna. Poi fare la media dei valori riportati in un'altra colonna utilizzando tre criteri di selezione (punto di misura, giorno (feriale, festivo), periodo di riferimento (diurno, notturno). Credo di essermi spiegato malissimo. Si può fare? Come? Tenete presente che sono veramente un principiante.
So che si può fare direttamente in excel; l'ho fatto, ma in excel devo rifare tutto ogni volta che cambio il file. Vorrei creare una routine generale.
Grazie
Walter

Offline nuzzopippo

  • python erectus
  • ***
  • Post: 228
  • Punti reputazione: 0
    • Mostra profilo
Re:Richiesta di aiuto per utilizzo openpyxl
« Risposta #1 il: Aprile 13, 2020, 19:32 »
Ciao @Walter

Conosco pochissimo le openpyxl ma si, sono convinto che quello che chiedi possa essere fatto con python, tenendo presente che le openpyxl hanno un supporto limitato per le formule ... ma python è comunque un linguaggio di programmazione e, magari, ci sono anche altri strumenti ...

Il punto sarebbe cosa effettivamente Tu stia chiedendo,  di manipolare i Tuoi fogli elettronici, una procedura che li crei direttamente partendo da una base dati oppure di scrivere una routine che Ti crei dei template da compilare?
I primi due casi implicano preliminarmente un robusto studio di python ed altro, per il terzo non è necessario alcun linguaggio di programmazione, potendosi utilizzare dei modelli, via che suppongo più semplice e che Ti consiglierei di valutare.

P.S.  la sezione del forum che non hai trovato è "Benvenuto e regolamento"

Offline Walter

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
Re:Richiesta di aiuto per utilizzo openpyxl
« Risposta #2 il: Aprile 13, 2020, 21:16 »
Grazie @nuzzopippo,
provo a spiegarmi meglio. Ho un file excel già popolato con alcune centinaia di righe. Devo creare una colonna "Giorno" che in ciascuna cella mi restituisca la stringa "Feriale" o "Festivo" in base al valore della cella nella colonna "Data" della stessa riga. Fatto ciò devo salvare il file. Questo è il primo passo, ma sarebbe già qualcosa.
Grazie

Offline nuzzopippo

  • python erectus
  • ***
  • Post: 228
  • Punti reputazione: 0
    • Mostra profilo
Re:Richiesta di aiuto per utilizzo openpyxl
« Risposta #3 il: Aprile 14, 2020, 09:29 »
...
provo a spiegarmi meglio. Ho un file excel già popolato con alcune centinaia di righe. Devo creare una colonna "Giorno" che in ciascuna cella mi restituisca la stringa "Feriale" o "Festivo" in base al valore della cella nella colonna "Data" della stessa riga. Fatto ciò devo salvare il file. Questo è il primo passo, ma sarebbe già qualcosa...

Questo non è che sia difficile, consultando il tutorial di openpyxl è stato semplice prepararTi un esempio, malgrado io non usi proprio excel e raramente la libreria in questione.

Supponiamo di avere un foglio elettronico "walter.xlsx" su cui foglio "Foglio1" abbiamo i dati dei lavoretti di quel factotum di Paperino con indicati i centri di costo, fatto così :
		Prestazioni Paolino Paperino			
Area     Ufficio     Data     Lavorato
Papersera Articoli 01/04/20 si
Papersera Articoli 02/04/20 si
Papersera Articoli 03/04/20 no
Deposito Lucidatura 04/04/20 si
Deposito Lucidatura 05/04/20 si
Papersera Articoli 06/04/20 Si
Papersera Articoli 07/04/20 no
Papersera Articoli 08/04/20 si
Papersera Composizione 09/04/20 si
Deposito Lucidatura 10/04/20 si
Papersera Articoli 11/04/20 si
Papersera Articoli 12/04/02 si
A B C D

L'ultima riga in fondo riporta la colonna in cui il dato è inserito.

Diciamo che vogliamo valutare le date nella colonna "C", che hanno come intestazione "Data" ed inserire in una colonna a piacere che denomineremo "Giorno" la valutazione se è un giorno "Feriale" (Lunedì-Sabato) o "Festivo" (domenica), il programma sotto trova la prima evenienza della intestazione "Data" nel foglio, chiede all'utente il numero di colonna in cui inserire la valutazione, crea ed intesta la colonna "Giorno" e la popola dei dati corrispondenti alla data, per infine salvare tutto nel file "walter_modificato.xlsx".
Per comodità si suppone che il file di script (lo ho chiamato "insert_column.py") sia nella stessa directory contenente "walter.xlsx", è uno script da lanciare da shell.

Il Codice :
# -*- coding: utf-8 -*-

import openpyxl
import datetime

# pre-impostazione dati per la elaborazione
file_orig = 'walter.xlsx'
sheet_name = 'Foglio1'
search_header = 'Data'
header_to_insert = 'Giorno'
file_dest = 'walter_modificato.xlsx'

def get_row_column(sh, header):
    '''
    Individua in un foglio la prima evenienza di una intestazione

    parametri:
    - sh     : il foglio in cui cercare
    - header : il testo in cui cercare

    return:
    un tupla di valori interi (riga, colonna)
    '''
    for i in range(sh.min_row, sh.max_row + 1):
        for j in range(sh.min_column, sh.max_column + 1):
            if sh.cell(row=i, column=j).value == header:
                return i, j
    return None

def insert_column_and_header(sh, column_number, row_header, header):
    '''
    Inserisce una nuova colonna in un foglio e vi scrive una intestazione

    parametri:
    - sh            : il foglio su cui operare
    - column_number : intero, il numero di colonna da inserire
    - row_header    : intero, la riga di intestazione
    - header        : stringa, il testo da inserire
    '''
    # inserisce una colonna prima della column_number
    sh.insert_cols(column_number)
    # la nuova colonna ha ora column_number, inserisce l'intestazione
    sh.cell(row=row_header, column=column_number).value = header

def evaluate_and_edit(sh, col_v, col_e):
    '''
    Valuta ricorsivamente le righe di una colonna col_v di un foglio
    se sogno oggetti datetime.datetime estrae la data e calcola se è
    un giorno lavorativo (lunedì-sabato) o festivo (domenica) a seconda
    inserisce "Feriale" o "festivo" in col_e sulla stessa riga

    parametri:
    - sh    : il foglio da manipolare
    - col_v : intero, la colonna da valuttare
    - col_e : intero, la colonna da editare
    '''
    for i in range(sh.min_row, sh.max_row + 1):
        dato = sh.cell(row=i, column=col_v).value
        tipo = str(type(dato))
        if 'datetime.datetime' in tipo:
            data = dato.date()
            if data.isoweekday() == 7:
                sh.cell(row=i, column=col_e).value = 'Festivo'
            else:
                sh.cell(row=i, column=col_e).value = 'Feriale'


if __name__ == '__main__':
    print('Avvio elaborazione di', file_orig)
    wb = openpyxl.load_workbook(file_orig)
    she = wb.get_sheet_by_name(sheet_name)
    if she:
        print('Foglio "%s" trovato' % (sheet_name))
    else:
        print('Foglio "%s" non trovato : Abbandono')
        exit()
    coords = get_row_column(she, search_header)
    if not coords:
        print(search_header, 'non trovato :  Abbandono')
        exit()
    print(search_header,
          'trovato riga %d colonna %d' %(coords[0], coords[1]),
          '\n')
    pos = input('Inserire posizione della colonna %s : ' % (header_to_insert))
    new_col = int(pos)
    insert_column_and_header(she, new_col, coords[0], header_to_insert)
    if new_col <= coords[1]:
        coords[1] += 1
    evaluate_and_edit(she, coords[1], new_col)
    wb.save(filename = file_dest)


Tieni presente che l'import di datetime avrebbe potuto essere evitato, lo ho messo per indicarTi la libreria di cui leggere la docs per eventuali dubbi, ho cercato di astrarlo quanto possibile senza strafare e  di spiegarne il funzionamento come meglio potevo.
Eventuali errori non vengono intercettati.

Provalo creandoti un foglio come indicato e vedi un po', per domande : c'è la docs di python e delle librerie coinvolte.

Ciao

[Edit] Dimenticavo :

Questo è l'output di sessione :

(pyxl_venv) NzP:~$ python insert_column.py
Avvio elaborazione di walter.xlsx
Foglio "Foglio1" trovato
Data trovato riga 2 colonna 3

Inserire posizione della colonna Giorno : 4
(pyxl_venv) NzP:~$


e questo è il contenuto del foglio salvato dalla esecuzione
		Prestazioni Paolino Paperino				
Area Ufficio Data Giorno Lavorato
Papersera Articoli 01/04/20 Feriale si
Papersera Articoli 02/04/20 Feriale si
Papersera Articoli 03/04/20 Feriale no
Deposito Lucidatura 04/04/20 Feriale si
Deposito Lucidatura 05/04/20 Festivo si
Papersera Articoli 06/04/20 Feriale Si
Papersera Articoli 07/04/20 Feriale no
Papersera Articoli 08/04/20 Feriale si
Papersera Composizione 09/04/20 Feriale si
Deposito Lucidatura 10/04/20 Feriale si
Papersera Articoli 11/04/20 Feriale si
Papersera Articoli 11/04/02 Feriale si
A B C D E
« Ultima modifica: Aprile 14, 2020, 09:37 da nuzzopippo »