Come leggere centinaia di migliaia di righe in Excel senza riempire subito la memoria
Questo articolo fornisce una soluzione di programmazione difensiva che include la riparazione delle dimensioni, il rilascio di sicurezza delle risorse e la verifica dell'integrità per risolvere i problemi di overflow della memoria e di troncamento dei dati legati alla lettura di file di grandi dimensioni in modalità sola lettura di openpyxl. Vengono chiarite le condizioni limite e gli standard di revisione manuale e vengono forniti i punti di collegamento specifici per il confronto e l'accettazione bilingue combinati con OmniDoc.
Come leggere una tabella di grandi dimensioni senza consumare memoria? Questo articolo è destinato agli sviluppatori e ai team di dati che necessitano di utilizzare Python per elaborare centinaia di migliaia di righe di Excel. Dopo la lettura, conoscerai i motivi dell'esplosione della memoria di file di grandi dimensioni e del troncamento dei dati e come utilizzare la modalità di sola lettura, la riparazione delle dimensioni e il rilascio delle risorse di openpyxl per prevenire questi problemi.
Gli esempi in questo articolo utilizzano campioni sintetici. Il codice è stato controllato con esempi in un ambiente isolato, ma ciò non è una garanzia di tutti i file reali o delle prestazioni del prodotto. Prima di elaborare documenti importanti, conservare gli originali e rivederli rispettando i limiti e gli elementi di accettazione nel testo.
Come leggere una tabella di grandi dimensioni senza consumare la memoria? Conclusione di una frase
Utilizza read_only=True per leggere in streaming file di grandi dimensioni e chiudere esplicitamente la cartella di lavoro dopo la lettura; se il numero di righe lette è ovviamente troppo piccolo, controllare prima le informazioni sulle dimensioni del file, quindi combinarle con il confronto manuale per confermare che i dati sono completi.
| la tua situazione | Pratiche consigliate | motivo |
|---|---|---|
| L'apertura di file di grandi dimensioni in modalità predefinita esaurisce rapidamente la memoria | Utilizza invece la lettura in streaming read_only=True | La modalità predefinita caricherà contemporaneamente in memoria tutti gli oggetti cella e i relativi stili, commenti e altri metadati |
| Legge solo le prime migliaia di righe e termina senza segnalare errori. | Utilizzare reset_dimensions() per riparare e rileggere e impostare il numero minimo di righe e la riga di fondo | La modalità di sola lettura considera attendibile il dimensions dichiarato nel file. Se è scritto in modo errato, l'iteratore terminerà anticipatamente. |
| Script ETL che esegue il looping di più file | Chiama wb.close() esplicitamente in un blocco finally | La mancata chiusura causerà la perdita dell'handle del file, attivando eventualmente OSError: Too many open files |
| Dati da utilizzare nei processi formali | Esporta i log rispetto al sistema di origine ed esegui la revisione manuale del campionamento | L'esecuzione del codice non significa che i dati siano corretti |
La causa diretta dell'esplosione della memoria o del troncamento dei dati durante la lettura di centinaia di migliaia di righe in Excel
Quando si utilizza load_workbook('huge.xlsx') per aprire una tabella con mezzo milione di righe, il programma potrebbe utilizzare fino a 8 GB di memoria in pochi secondi oppure potrebbe terminare dopo aver letto solo le prime 1.000 righe.
Il motivo del primo è che la modalità predefinita carica in memoria tutti gli oggetti cella e i relativi stili, commenti e altri metadati contemporaneamente. Quest'ultimo perché in modalità read_only=True, openpyxl si fida completamente dell'attributo dimensions dichiarato all'interno del file per perseguire le prestazioni.
Se il sistema che ha generato il file (come un vecchio modulo di esportazione ERP o una libreria Python non standard) scrive questi metadati in modo errato, l'iteratore terminerà prematuramente senza generare alcuna eccezione. Non si tratta di un bug del codice, ma di un divario tra le specifiche del formato e i dati del mondo reale che deve essere colmato attraverso una programmazione difensiva.
Metodo di apertura e rilascio delle risorse corretti in modalità sola lettura
read_only=True è il percorso principale per la gestione di file di grandi dimensioni, ma modifica la gestione del ciclo di vita degli oggetti. Le cartelle di lavoro ordinarie rilasceranno automaticamente le risorse durante la garbage collection, mentre le cartelle di lavoro di sola lettura mantengono i riferimenti al flusso di file ZIP e al parser XML nella parte inferiore e devono chiamare esplicitamente wb.close(). Per istruzioni ufficiali sulla modalità di sola lettura, fare riferimento a documentazione ufficiale delle modalità ottimizzate openpyxl.
Dimenticare questo passaggio in uno script ETL che esegue il loop su più file può causare perdite di gestione dei file, attivando infine OSError: Too many open files. Questo tipo di errore viene spesso rilevato dopo diverse ore di funzionamento ed è estremamente difficile da risolvere.
Inoltre, la modalità di sola lettura restituisce ReadOnlyCell invece dell'oggetto Cell standard. Non supporta l'accesso ad attributi come stili e annotazioni, né consente la ricerca inversa o la modifica dei valori tramite coordinate. Se ottieni informazioni sull'area unita o imposti il colore della cella durante l'iterazione, otterrai AttributeError. Questo limite è intenzionale per mantenere un'impronta di memoria quasi costante.
📊 Confronto fondamentale
| Voce comparativa | Modalità predefinita | modalità sola_lettura |
|---|---|---|
| Utilizzo della memoria | Carica tutti gli oggetti e i metadati della cella contemporaneamente, i file di grandi dimensioni possono facilmente esaurire la memoria | Lettura in streaming, l'utilizzo della memoria è quasi costante |
| L'oggetto cella restituito | Cell standard | ReadOnlyCell |
| Stile, accesso alle annotazioni | supporto | Non supportato, l'accesso risulterà in AttributeError |
| Modifica il valore o imposta il colore | supporto | Non supportato |
dimensions dipende dal file | non dipendente da | Le dipendenze, se scritte in modo errato, l'iterazione potrebbe terminare anticipatamente |
| Rilascio di risorse | Rilasciato automaticamente durante la garbage collection | Richiede una chiamata esplicita a wb.close() |
Esempio di sintesi: riparazione delle dimensioni e verifica della sicurezza dell'iterazione
Il codice seguente mostra un tipico processo di lettura difensiva. Si noti che questo è un esempio sintetico utilizzato per dimostrare la struttura logica, non il risultato dell'elaborazione dei dati di produzione reali. È necessario preparare un file denominato input_large.xlsx per eseguire questo script e dovrebbe essere eseguito in un ambiente isolato che blocchi le versioni dipendenti. L'esempio non include operazioni di rete, comandi shell o credenziali riservate.
from openpyxl import load_workbook
# 合成示例:演示read_only模式下的安全读取与维度校验
# 依赖:openpyxl (需在项目requirements中锁定具体版本)
# 注意:需读者自备 input_large.xlsx,本示例不包含真实数据
def safe_read_large_excel(filepath, expected_min_rows=1000):
"""
安全读取大Excel文件,包含维度修复与完整性校验。
:param filepath: Excel文件路径
:param expected_min_rows: 业务预期的最小行数阈值
:return: 实际读取的行数
"""
wb = load_workbook(filename=filepath, read_only=True)
try:
ws = wb.active
# 检查并修复可能错误的维度声明
# calculate_dimension() 可能返回 'A1:A1' 或其他不准确范围
dim = ws.calculate_dimension()
if dim == "A1:A1" or not dim:
# 重置维度以强制扫描实际数据区域
# 警告:若文件完全无维度信息,此操作可能遍历全表(104万行)
ws.reset_dimensions()
row_count = 0
header = None
for row in ws.iter_rows(values_only=True):
if row_count == 0:
header = row
assert header is not None and any(v is not None for v in header), \
"首行不应为空或全None"
row_count += 1
# 模拟业务处理,避免全量加载到内存
if row_count % 10000 == 0:
print(f"已处理 {row_count} 行")
# 校验读取完整性
assert row_count >= expected_min_rows, \
f"行数不足: 期望>={expected_min_rows}, 实际={row_count}。请检查源文件或维度设置。"
return row_count
finally:
# 必须显式关闭,防止句柄泄漏
wb.close()
# 使用示例(需替换为真实文件路径)
# total = safe_read_large_excel("input_large.xlsx", expected_min_rows=50000)
La chiave di questo codice non è la lettura in sé, ma i tre livelli di protezione:
- Reimpostazione dimensione: risolto il problema
dimensionsnella dichiarazione del file per evitare la fine prematura dell'iteratore. - Conteggio flussi: conta il numero di righe durante la lettura per facilitare il confronto con le aspettative.
- Chiusura forzata in
finally: indipendentemente dal fatto che la lettura abbia avuto successo o che si sia verificato un errore nel mezzo, le risorse del file vengono rilasciate.
expected_min_rows non è una soglia standard del settore, ma un risultato aziendale basato sulla conoscenza precedente dei dati di origine. Se il numero effettivo di righe è inferiore a questo valore, il file potrebbe essere danneggiato o la riparazione della dimensione non è riuscita e dovresti interrompere in questo momento invece di accettare silenziosamente dati incompleti.
Criteri di accettazione e limiti della revisione manuale
Solo perché il codice può essere eseguito non significa che i dati siano corretti. La tabella seguente elenca le eccezioni tipiche che possono essere riscontrate nei progetti reali e come affrontarle, distinguendo l'ambito che l'automazione può coprire e gli scenari che richiedono un intervento manuale.
| Osservare i fenomeni | Possibili ragioni | Elaborazione automatizzata | Requisiti di revisione manuale |
|---|---|---|---|
| Il numero di righe lette è molto inferiore al previsto | errore attributo dimensioni | Prova a rileggere dopo reset_dimensions | Confronta il registro di esportazione del sistema di origine per confermare se è realmente mancante. |
| Il tempo richiesto aumenta notevolmente dopo reset_dimensions | Il file non contiene informazioni sulle dimensioni, il che comporta una scansione completa della tabella | Imposta il limite massimo di righe o i criteri di terminazione delle righe vuote | Valuta la qualità del generatore di file e apporta correzioni a monte |
| Alcuni valori delle celle sono Nessuno | Celle unite o formula che non viene calcolata | registra la posizione, salta | Controlla se l'area nel file originale è unita visivamente |
| iter_rows a metà StopIteration | Flusso XML danneggiato o ZIP frammentato | Cattura l'eccezione e registra l'offset | Apri manualmente con Excel o WPS e verifica l'area corrispondente |
| La memoria cresce lentamente | Non chiuso o cache non rilasciata | Forza il monitoraggio post-gc.collect() | Controlla se esiste una variabile globale che contiene un riferimento di cella |
| Il nome del campo dell'intestazione contiene caratteri invisibili | Problema di codifica del sistema di esportazione | strip() pulito | Confermare la relazione di mappatura dei campi con la parte commerciale |
Nota speciale: reset_dimensions() non è una panacea. Se nel file stesso non vengono scritte informazioni sulla dimensione, questo metodo potrebbe estendere l'intervallo fino al limite superiore del foglio di lavoro (1048576 righe), determinando un attraversamento non valido o addirittura un timeout. A questo punto, max_row dovrebbe essere utilizzato per impostare manualmente un limite superiore ragionevole oppure dovrebbe essere terminato attivamente quando si incontrano N righe vuote in una riga. Questi giudizi non possono essere espressi solo tramite il codice e richiedono il supporto della conoscenza del dominio.
🎯Quale metodo è adatto a te?
Se è necessario elaborare tabelle con centinaia di migliaia di righe contemporaneamente
Utilizza la lettura in streaming read_only=True per evitare l'esplosione della memoria in modalità predefinita.
Se lo script esegue il loop su più file
Chiama wb.close() esplicitamente in un blocco finally per evitare perdite di gestione.
Se il numero di righe lette è significativamente inferiore ai dati di origine
Per prima cosa controlla se dimensions è scritto in modo errato, prova reset_dimensions() e poi rileggilo e confrontalo con il registro di esportazione del sistema sorgente.
Se hai bisogno di leggere stili o commenti
Queste proprietà non sono supportate in modalità di sola lettura e devono essere utilizzate invece in modalità predefinita o gestite separatamente in un altro processo.
Voce di esecuzione del campione di memoria
Il codice seguente viene eseguito dopo la funzione precedente e utilizza solo dati sintetici e non legge il file del cliente.
from io import BytesIO
from openpyxl import Workbook
source = Workbook()
source.active.append(["id", "value"])
source.active.append(["A", 1])
source.active.append(["B", 2])
out = BytesIO()
source.save(out)
out.seek(0)
assert safe_read_large_excel(out, expected_min_rows=3) == 3
Utilizza questa lista di controllo per la traduzione dei documenti
Per prima cosa decidi quale contenuto è testo e quale è formula e codifica aziendale, quindi traduci la tabella. Il controllo post-traduzione non solo verifica se il cinese è stato convertito nella lingua di destinazione, ma conferma anche se le formule, gli identificatori e le relazioni di riferimento sono stati modificati.
OmniDoc (portale del prodotto) fornisce un portale di traduzione di documenti multiformato e il sito Web ufficiale introduce funzioni OCR, glossario e confronto bilingue. Per i team che desiderano lavorare direttamente dai file, questo è un percorso che vale la pena valutare con campioni reali. Utilizza file non sensibilizzati che sei autorizzato a caricare e utilizza gli elementi di controllo in questo articolo per esaminare i risultati. Questo articolo non afferma che OmniDoc utilizza le librerie open source o gli algoritmi interni nell'articolo, né utilizza esempi per sostituire i test sulle prestazioni del prodotto.
❓ Domande frequenti (FAQ)
1. Perché termina a metà della lettura e non viene segnalato alcun errore?
Poiché la modalità di sola lettura considera attendibile il dimensions dichiarato dal file. Se il sistema di compilazione scrive questi metadati in modo errato, l'iteratore terminerà prematuramente senza generare un'eccezione.
2. Tutti i file di grandi dimensioni possono essere risolti con reset_dimensions()?
non può. Se il file stesso non dispone di informazioni sulla dimensione, questo metodo può estendere l'intervallo a 1048576 righe, causando un timeout e deve essere combinato con il max_row o il criterio di terminazione di righe vuote continue.
3. Perché non riesco a leggere gli stili o modificare le celle in modalità di sola lettura?
La modalità di sola lettura restituisce ReadOnlyCell, non supporta l'accesso allo stile e alle annotazioni e non consente la modifica dei valori. Questo per mantenere un ingombro di memoria quasi costante.
4. Cosa devo controllare dopo aver tradotto il modulo?
Oltre alla lingua corretta, controlla se le formule, gli identificatori e le relazioni di riferimento sono stati modificati.
📝 Riepilogo
La chiave per leggere tabelle di grandi dimensioni risiede nella lettura in streaming, nella verifica delle dimensioni e nel rilascio tempestivo delle risorse. Il codice è solo il punto di partenza e la completezza dei dati dipende dal confronto e dalla revisione manuale.
Provalo subito: carica il documento per iniziare la traduzione, mantenendo il layout originale


