복붙노트

[PYTHON] 전체 문서를 메모리에로드하지 않고도 Excel 문서의 행 수를 얻을 수 있습니까?

PYTHON

전체 문서를 메모리에로드하지 않고도 Excel 문서의 행 수를 얻을 수 있습니까?

거대한 Excel 2007 파일을 처리하는 응용 프로그램에서 작업 중이며 OpenPyXL을 사용하고 있습니다. OpenPyXL에는 Excel 파일을 읽는 두 가지 방법이 있습니다. 한 가지 방법은 전체 문서를 한 번에 메모리에로드하는 "일반적인"방법과 반복자를 사용하여 한 줄씩 읽는 방법입니다.

문제는 iterator 메서드를 사용할 때 열 너비 및 행 / 열 개수와 같은 문서 메타 데이터를 얻지 못하므로이 데이터가 실제로 필요하다는 것입니다. 이 데이터는 Excel 문서 상단에 저장되어 있다고 가정하므로 액세스 할 수 있도록 전체 10MB 파일을 메모리에로드 할 필요가 없습니다.

그래서, 먼저 전체 문서를 메모리에로드하지 않고 행 / 열 개수와 열 너비를 확인하는 방법이 있습니까?

해결법

  1. ==============================

    1.Hubro가 말한 것에 덧붙여, 분명히 get_highest_row ()는 더 이상 사용되지 않습니다. max_row 및 max_column 속성을 사용하면 행 및 열 개수가 반환됩니다. 예 :

    Hubro가 말한 것에 덧붙여, 분명히 get_highest_row ()는 더 이상 사용되지 않습니다. max_row 및 max_column 속성을 사용하면 행 및 열 개수가 반환됩니다. 예 :

        wb = load_workbook(path, use_iterators=True)
        sheet = wb.worksheets[0]
    
        row_count = sheet.max_row
        column_count = sheet.max_column
    
  2. ==============================

    2.OpenPyXL (IterableWorksheet)의 소스 코드를 살펴보면서 반복기 워크 시트에서 열과 행 수를 얻는 방법을 알아 냈습니다.

    OpenPyXL (IterableWorksheet)의 소스 코드를 살펴보면서 반복기 워크 시트에서 열과 행 수를 얻는 방법을 알아 냈습니다.

    wb = load_workbook(path, use_iterators=True)
    sheet = wb.worksheets[0]
    
    row_count = sheet.get_highest_row() - 1
    column_count = letter_to_index(sheet.get_highest_column()) + 1
    

    IterableWorksheet.get_highest_column은 Excel에서 볼 수있는 열 문자가 포함 된 문자열을 반환합니다 (예 : "A", "B", "C"등. 따라서 컬럼 문자를 0 기반 인덱스로 변환하는 함수도 작성했습니다.

    def letter_to_index(letter):
        """Converts a column letter, e.g. "A", "B", "AA", "BC" etc. to a zero based
        column index.
    
        A becomes 0, B becomes 1, Z becomes 25, AA becomes 26 etc.
    
        Args:
            letter (str): The column index letter.
        Returns:
            The column index as an integer.
        """
        letter = letter.upper()
        result = 0
    
        for index, char in enumerate(reversed(letter)):
            # Get the ASCII number of the letter and subtract 64 so that A
            # corresponds to 1.
            num = ord(char) - 64
    
            # Multiply the number with 26 to the power of `index` to get the correct
            # value of the letter based on it's index in the string.
            final_num = (26 ** index) * num
    
            result += final_num
    
        # Subtract 1 from the result to make it zero-based before returning.
        return result - 1
    

    그래도 열 크기를 가져 오는 방법을 찾지 못했습니다. 따라서 고정 폭 글꼴을 사용하고 응용 프로그램에서 열을 자동으로 크기를 조정하기로 결정했습니다.

  3. ==============================

    3.이것은 극단적으로 뒤죽박죽 일 수 있습니다. 그러나 분명히 빠져있을 수도 있습니다. 그러나 반복 가능한 워크 시트의 column_dimensions에 OpenPyXL을 채우지 않으면 (위에서 설명한 내용을 참조하십시오), 모든 것을로드하지 않고 열 크기를 직접 확인할 수있는 유일한 방법은 xml을 직접 구문 분석하는 것입니다 :

    이것은 극단적으로 뒤죽박죽 일 수 있습니다. 그러나 분명히 빠져있을 수도 있습니다. 그러나 반복 가능한 워크 시트의 column_dimensions에 OpenPyXL을 채우지 않으면 (위에서 설명한 내용을 참조하십시오), 모든 것을로드하지 않고 열 크기를 직접 확인할 수있는 유일한 방법은 xml을 직접 구문 분석하는 것입니다 :

    from xml.etree.ElementTree import iterparse
    from openpyxl import load_workbook
    wb=load_workbook("/path/to/workbook.xlsx", use_iterators=True)
    ws=wb.worksheets[0]
    xml = ws._xml_source
    xml.seek(0)
    
    for _,x in iterparse(xml):
    
        name= x.tag.split("}")[-1]
        if name=="col":
            print "Column %(max)s: Width: %(width)s"%x.attrib # width = x.attrib["width"]
    
        if name=="cols":
            print "break before reading the rest of the file"
            break
    
  4. ==============================

    4.https://pythonhosted.org/pyexcel/iapi/pyexcel.sheets.Sheet.html  참조 : row_range () 행 범위를 가져 오는 유틸리티 함수

    https://pythonhosted.org/pyexcel/iapi/pyexcel.sheets.Sheet.html  참조 : row_range () 행 범위를 가져 오는 유틸리티 함수

    pyexcel을 사용하는 경우 row_range는 최대 행을 가져올 수 있습니다.

    python 3.4 테스트 합격.

  5. from https://stackoverflow.com/questions/13377793/is-it-possible-to-get-an-excel-documents-row-count-without-loading-the-entire-d by cc-by-sa and MIT license