예제 #1
0
def fitauto(sheet):
    """
	Cette fonction permet d'ajuster la taille des colonnes en fonction de la taille de cellules max afin d'avoir un contenu
	homogène.
    ----------
    sheet : WorkBook
		Feuille d'un fichier excel
    """
    from openpyxl.utils.cell import _get_column_letter
    column_widths = []
    for row in sheet.iter_rows():
        for i, cell in enumerate(
                row):  #Pour chaque cellule de la feuille par ligne
            try:
                size = len(str(cell.value))
                column_widths[i] = max(
                    column_widths[i], size
                )  #Compare la valeur de la largeur de colonne à celle de ces cellules
                # print(column_widths)
                #print(str(cell.value) + " && " + str(column_widths[i]) + " index: " + str(i))
            except IndexError:
                column_widths.append(len(str(cell.value)))
    print(column_widths)
    if column_widths.__len__() == 9:
        column_widths[
            8] = 100  #Changement de la largeur de colonne qui sera fixe pour la colonne tour de parole
    for i, column_width in enumerate(column_widths):
        # print(column_width)
        sheet.column_dimensions[_get_column_letter(
            i + 1
        )].width = column_width + 1  #On fixe la taille max selon le tableau column_widths
예제 #2
0
    def get_sheet_headings(self, sheet_name):
        worksheet = self.workbook[self.sheet_names_map[sheet_name]]
        sheet_configuration = self.sheet_configuration[self.sheet_names_map[sheet_name]]
        configuration_line = 1 if sheet_configuration else 0
        if not sheet_configuration:
            sheet_configuration = self.base_configuration
        if not self.use_configuration:
            sheet_configuration = {}

        skip_rows = sheet_configuration.get("skipRows", 0)
        if sheet_configuration.get("ignore") or (
            sheet_configuration.get("hashcomments") and sheet_name.startswith("#")
        ):
            # returning empty headers is a proxy for no data in the sheet.
            return []

        if self.vertical_orientation:
            return [
                cell.value
                for cell in worksheet[_get_column_letter(skip_rows + 1)][
                    configuration_line:
                ]
            ]

        try:
            return [
                cell.value for cell in worksheet[skip_rows + configuration_line + 1]
            ]
        except IndexError:
            # If the heading line is after data in the spreadsheet. i.e when skipRows
            return []
예제 #3
0
    def get_sheet_lines(self, sheet_name):
        sheet_configuration = self.sheet_configuration[self.sheet_names_map[sheet_name]]
        configuration_line = 1 if sheet_configuration else 0
        if not sheet_configuration:
            sheet_configuration = self.base_configuration
        if not self.use_configuration:
            sheet_configuration = {}

        skip_rows = sheet_configuration.get("skipRows", 0)
        header_rows = sheet_configuration.get("headerRows", 1)


        worksheet = self.workbook[self.sheet_names_map[sheet_name]]
        if self.vertical_orientation:
            header_row = worksheet[_get_column_letter(skip_rows + 1)]
            remaining_rows = worksheet.iter_cols(min_col=skip_rows + header_rows + 1)
            if configuration_line:
                header_row = header_row[1:]
                remaining_rows = worksheet.iter_cols(min_col=skip_rows + header_rows + 1, min_row=2)
        else:
            header_row = worksheet[skip_rows + configuration_line + 1]
            remaining_rows = worksheet.iter_rows(min_row=skip_rows + configuration_line + header_rows + 1)

        coli_to_header = {}
        for i, header in enumerate(header_row):
            if header.value is None:
                continue
            if sheet_configuration.get("hashcomments") and str(header.value).startswith('#'):
                continue
            coli_to_header[i] = header.value
        for row in remaining_rows:
            yield OrderedDict((coli_to_header[i], x.value) for i, x in enumerate(row) if i in coli_to_header)
예제 #4
0
    def get_sheet_lines(self, sheet_name):
        sheet_configuration = self.sheet_configuration[
            self.sheet_names_map[sheet_name]]
        configuration_line = 1 if sheet_configuration else 0
        if not sheet_configuration:
            sheet_configuration = self.base_configuration
        if not self.use_configuration:
            sheet_configuration = {}

        skip_rows = sheet_configuration.get("skipRows", 0)
        header_rows = sheet_configuration.get("headerRows", 1)

        worksheet = self.workbook[self.sheet_names_map[sheet_name]]
        if self.vertical_orientation:
            header_row = worksheet[_get_column_letter(skip_rows + 1)]
            remaining_rows = worksheet.iter_cols(min_col=skip_rows +
                                                 header_rows + 1)
            if configuration_line:
                header_row = header_row[1:]
                remaining_rows = worksheet.iter_cols(min_col=skip_rows +
                                                     header_rows + 1,
                                                     min_row=2)
        else:
            header_row = worksheet[skip_rows + configuration_line + 1]
            remaining_rows = worksheet.iter_rows(
                min_row=skip_rows + configuration_line + header_rows + 1)

        coli_to_header = {}
        for i, header in enumerate(header_row):
            coli_to_header[i] = header.value

        for row in remaining_rows:
            output_row = OrderedDict()
            for i, x in enumerate(row):
                header = coli_to_header[i]
                value = x.value
                if not header:
                    # None means that the cell will be ignored
                    value = None
                elif (sheet_configuration.get("hashcomments")
                      and isinstance(header, str) and header.startswith("#")):
                    # None means that the cell will be ignored
                    value = None
                output_row[header] = value
            yield output_row
예제 #5
0
    def get_sheet_headings(self, sheet_name):
        worksheet = self.workbook[self.sheet_names_map[sheet_name]]
        sheet_configuration = self.sheet_configuration[self.sheet_names_map[sheet_name]]
        configuration_line = 1 if sheet_configuration else 0
        if not sheet_configuration:
            sheet_configuration = self.base_configuration
        if not self.use_configuration:
            sheet_configuration = {}

        skip_rows = sheet_configuration.get("skipRows", 0)
        if (sheet_configuration.get("ignore") or
            (sheet_configuration.get("hashcomments") and sheet_name.startswith('#'))):
            # returning empty headers is a proxy for no data in the sheet.
            return []

        if self.vertical_orientation:
            return [cell.value for cell in worksheet[_get_column_letter(skip_rows + 1)][configuration_line:]]

        try:
            return [cell.value for cell in worksheet[skip_rows + configuration_line + 1]]
        except IndexError:
            # If the heading line is after data in the spreadsheet. i.e when skipRows
            return []
예제 #6
0
    def do_unflatten(self):
        main_sheet_by_ocid = OrderedDict()
        sheets = list(self.get_sub_sheets_lines())
        for i, sheet in enumerate(sheets):
            sheet_name, lines = sheet
            try:
                actual_headings = self.get_sheet_headings(sheet_name)
                # If sheet is empty or too many lines have been skipped
                if not actual_headings:
                    continue
                found = OrderedDict()
                last_col = len(actual_headings)
                # We want to ignore data in earlier columns, so we look
                # through the data backwards
                for i, actual_heading in enumerate(reversed(actual_headings)):
                    if actual_heading is None:
                        continue
                    if actual_heading in found:
                        found[actual_heading].append((last_col - i) - 1)
                    else:
                        found[actual_heading] = [i]
                for actual_heading in reversed(found):
                    if len(found[actual_heading]) > 1:
                        keeping = found[actual_heading][0]  # noqa
                        ignoring = found[actual_heading][1:]
                        ignoring.reverse()
                        if len(ignoring) >= 3:
                            warn(
                                (
                                    'Duplicate heading "{}" found, ignoring '
                                    "the data in columns {} and {}."
                                ).format(
                                    actual_heading,
                                    ", ".join(
                                        [
                                            _get_column_letter(x + 1)
                                            for x in ignoring[:-1]
                                        ]
                                    ),
                                    _get_column_letter(ignoring[-1] + 1),
                                ),
                                DataErrorWarning,
                            )
                        elif len(found[actual_heading]) == 3:
                            warn(
                                (
                                    'Duplicate heading "{}" found, ignoring '
                                    "the data in columns {} and {}."
                                ).format(
                                    actual_heading,
                                    _get_column_letter(ignoring[0] + 1),
                                    _get_column_letter(ignoring[1] + 1),
                                ),
                                DataErrorWarning,
                            )
                        else:
                            warn(
                                (
                                    'Duplicate heading "{}" found, ignoring '
                                    "the data in column {}."
                                ).format(
                                    actual_heading, _get_column_letter(ignoring[0] + 1),
                                ),
                                DataErrorWarning,
                            )
            except NotImplementedError:
                # The ListInput type used in the tests doesn't support getting headings.
                actual_headings = None
            for j, line in enumerate(lines):
                if all(x is None or x == "" for x in line.values()):
                    # if all(x == '' for x in line.values()):
                    continue
                root_id_or_none = line.get(self.root_id) if self.root_id else None
                cells = OrderedDict()
                for k, header in enumerate(line):
                    heading = actual_headings[k] if actual_headings else header
                    if self.vertical_orientation:
                        # This is misleading as it specifies the row number as the distance vertically
                        # and the horizontal 'letter' as a number.
                        # https://github.com/OpenDataServices/flatten-tool/issues/153
                        cells[header] = Cell(
                            line[header], (sheet_name, str(k + 1), j + 2, heading)
                        )
                    else:
                        cells[header] = Cell(
                            line[header],
                            (sheet_name, _get_column_letter(k + 1), j + 2, heading),
                        )
                unflattened = unflatten_main_with_parser(
                    self.parser, cells, self.timezone, self.xml, self.id_name
                )
                if root_id_or_none not in main_sheet_by_ocid:
                    main_sheet_by_ocid[root_id_or_none] = TemporaryDict(
                        self.id_name, xml=self.xml
                    )

                def inthere(unflattened, id_name):
                    if self.xml:
                        return unflattened[id_name]["text()"].cell_value
                    else:
                        return unflattened[id_name].cell_value

                if (
                    self.id_name in unflattened
                    and inthere(unflattened, self.id_name)
                    in main_sheet_by_ocid[root_id_or_none]
                ):
                    if self.xml:
                        unflattened_id = unflattened.get(self.id_name)[
                            "text()"
                        ].cell_value
                    else:
                        unflattened_id = unflattened.get(self.id_name).cell_value
                    merge(
                        main_sheet_by_ocid[root_id_or_none][unflattened_id],
                        unflattened,
                        {
                            "sheet_name": sheet_name,
                            "root_id": self.root_id,
                            "root_id_or_none": root_id_or_none,
                            "id_name": self.id_name,
                            self.id_name: unflattened_id,
                        },
                    )
                else:
                    main_sheet_by_ocid[root_id_or_none].append(unflattened)
        temporarydicts_to_lists(main_sheet_by_ocid)
        return sum(main_sheet_by_ocid.values(), [])
예제 #7
0
def report_from_template(dft, df_cy16, filename):
    # Load the Template
    wb = load_workbook(settings.BASE_DIR + "/media/reports/KPI_Template.xlsx")

    # select the data sheet
    ws_data = wb.get_sheet_by_name("Data")
    wb.remove_sheet(ws_data)
    ws_data = wb.create_sheet('Data', 0)
    for r in dataframe_to_rows(dft, index=True, header=True):
        ws_data.append(r)

    # ws_chart = wb.create_sheet('Chart')
    # img = openpyxl.drawing.image.Image('7.jpg')
    # img.anchor(ws_chart.cell('C4'))
    # ws_chart.add_image(img)

    # select the sheet
    ws = wb.get_sheet_by_name("CY16")

    # Get the last row
    end_row = ws.max_row

    #####################################################################################################
    #
    # Integrate Code Above
    #
    #####################################################################################################

    index_col_cells, col_rows = get_cell_refs_for_index_and_cols()

    #####################################################################################################

    # Styles
    # We need to make sure to manually edit the template file that we are using in order to ensure that
    # our formatting during the script works appropriately

    # Insert Column Headers
    for i, col in enumerate(list(df_cy16.columns)):
        ws[str(_get_column_letter(i + 2) + "1")].value = col

    # Index of DataFrame
    zipped_ref_and_index_values = zip(index_col_cells, list(df_cy16.index))

    for input_ref_value in zipped_ref_and_index_values:
        ws[input_ref_value[0]].value = input_ref_value[1]
        ws[input_ref_value[0]].alignment = Alignment(horizontal='right')

    # All Columns in DataFrame
    for i, col_name in enumerate(list(df_cy16.columns)):
        col_cell_refs = [
            str(_get_column_letter(i + 2) + row_ref) for row_ref in col_rows
        ]
        zipped_ref_and_col_values = zip(col_cell_refs,
                                        list(df_cy16.ix[:, i].values))

        for input_ref_value in zipped_ref_and_col_values:
            ws[input_ref_value[0]].value = input_ref_value[1]
            ws[input_ref_value[0]].alignment = Alignment(horizontal='right')

    # Insert Remaining Table Headers specific to this Table
    table_headers = [
        'Program Summary', 'ADM Optimization', 'ADM Stock Outs',
        'ADM Scan Rate on Refill Transactions'
    ]
    table_headers_refs = ['A2', 'A8', 'A21', 'A32']
    zipped_ref_and_table_headers = zip(table_headers_refs, table_headers)

    for input_ref_value in zipped_ref_and_table_headers:
        ws[input_ref_value[0]].value = input_ref_value[1]
        ws[input_ref_value[0]].alignment = Alignment(horizontal='right')

    wb.save(filename)
예제 #8
0
 def do_unflatten(self):
     main_sheet_by_ocid = OrderedDict()
     sheets = list(self.get_sub_sheets_lines())
     for i, sheet in enumerate(sheets):
         sheet_name, lines = sheet
         try:
             actual_headings = self.get_sheet_headings(sheet_name)
             # If sheet is empty or too many lines have been skipped
             if not actual_headings:
                 continue
             found = OrderedDict()
             last_col = len(actual_headings)
             # We want to ignore data in earlier columns, so we look
             # through the data backwards
             for i, actual_heading in enumerate(reversed(actual_headings)):
                 if actual_heading is None:
                     continue
                 if actual_heading in found:
                     found[actual_heading].append((last_col-i)-1)
                 else:
                     found[actual_heading] = [i]
             for actual_heading in reversed(found):
                 if len(found[actual_heading]) > 1:
                     keeping = found[actual_heading][0]
                     ignoring = found[actual_heading][1:]
                     ignoring.reverse()
                     if len(ignoring) >= 3:
                         warn(
                             (
                                 'Duplicate heading "{}" found, ignoring '
                                 'the data in columns {} and {}.'
                             ).format(
                                 actual_heading,
                                 ', '.join(
                                     [_get_column_letter(x+1) for x in ignoring[:-1]]
                                 ),
                                 _get_column_letter(ignoring[-1] + 1),
                             ),
                             DataErrorWarning
                         )
                     elif len(found[actual_heading]) == 3:
                         warn(
                             (
                                 'Duplicate heading "{}" found, ignoring '
                                 'the data in columns {} and {}.'
                             ).format(
                                 actual_heading,
                                 _get_column_letter(ignoring[0] + 1),
                                 _get_column_letter(ignoring[1] + 1),
                             ),
                             DataErrorWarning
                         )
                     else:
                         warn(
                             (
                                 'Duplicate heading "{}" found, ignoring '
                                 'the data in column {}.'
                             ).format(
                                 actual_heading,
                                 _get_column_letter(ignoring[0]+1),
                             ),
                             DataErrorWarning
                         )
         except NotImplementedError:
             # The ListInput type used in the tests doesn't support getting headings.
             actual_headings = None
         for j, line in enumerate(lines):
             if all(x is None or x == '' for x in line.values()):
             #if all(x == '' for x in line.values()):
                 continue
             root_id_or_none = line.get(self.root_id) if self.root_id else None
             cells = OrderedDict()
             for k, header in enumerate(line):
                 heading = actual_headings[k] if actual_headings else header
                 if self.vertical_orientation:
                     # This is misleading as it specifies the row number as the distance vertically
                     # and the horizontal 'letter' as a number.
                     # https://github.com/OpenDataServices/flatten-tool/issues/153
                     cells[header] = Cell(line[header], (sheet_name, str(k+1), j+2, heading))
                 else:
                     cells[header] = Cell(line[header], (sheet_name, _get_column_letter(k+1), j+2, heading))
             unflattened = unflatten_main_with_parser(self.parser, cells, self.timezone, self.xml, self.id_name)
             if root_id_or_none not in main_sheet_by_ocid:
                 main_sheet_by_ocid[root_id_or_none] = TemporaryDict(self.id_name, xml=self.xml)
             def inthere(unflattened, id_name):
                 if self.xml:
                     return unflattened[id_name]['text()'].cell_value
                 else:
                     return unflattened[id_name].cell_value
             if self.id_name in unflattened and inthere(unflattened, self.id_name) in main_sheet_by_ocid[root_id_or_none]:
                 if self.xml:
                     unflattened_id = unflattened.get(self.id_name)['text()'].cell_value
                 else:
                     unflattened_id = unflattened.get(self.id_name).cell_value
                 merge(
                     main_sheet_by_ocid[root_id_or_none][unflattened_id],
                     unflattened,
                     {
                         'sheet_name': sheet_name,
                         'root_id': self.root_id,
                         'root_id_or_none': root_id_or_none,
                         'id_name': self.id_name,
                         self.id_name: unflattened_id
                     }
                 )
             else:
                 main_sheet_by_ocid[root_id_or_none].append(unflattened)
     temporarydicts_to_lists(main_sheet_by_ocid)
     return sum(main_sheet_by_ocid.values(), [])
예제 #9
0
                    style = "date"
                elif "€" in row[key]:
                    style = "currency"
                else:
                    try:
                        num = int(row[key])
                        style = "numeric"
                    except ValueError:
                        style = "text"
                # write cell;
                cell.style = style
                cell.value = row[key]

        # apply width values;
        for c, cell_width in enumerate(column_widths, start_column):
            column = _get_column_letter(c)
            sheet.column_dimensions[column].width = cell_width

    # create excel file and remove csv.
    try:
        book.save("generatedata.com.xlsx")
    except OSError as error:
        print("ERROR saving excel file.", error)
        sys.exit(1)
    else:
        send2trash("generatedata.com.csv")
        sys.exit(0)

elif os.path.exists("generatedata.com.xlsx"):
    # load excel file;
    book = openpyxl.load_workbook(filename="generatedata.com.xlsx")