示例#1
0
    def _generate_spreadsheet_data(cls, request, out, report, *args, **kwargs):
        # Create a workbook
        wb = Workbook(write_only=True)
        ws = wb.create_sheet(title=report.name)

        # Create a named style for the header row
        readlonlyheaderstyle = NamedStyle(name="readlonlyheaderstyle")
        readlonlyheaderstyle.fill = PatternFill(fill_type="solid",
                                                fgColor="d0ebfb")
        wb.add_named_style(readlonlyheaderstyle)

        # Run the query
        conn = None
        try:
            conn = create_connection(request.database)
            comment = CellComment(force_text(_("Read only")),
                                  "Author",
                                  height=20,
                                  width=80)
            with conn.cursor() as cursor:
                sqlrole = settings.DATABASES[request.database].get(
                    "SQL_ROLE", "report_role")
                if sqlrole:
                    cursor.execute("set role %s" % (sqlrole, ))
                cursor.execute(sql=cls.getSQL(report.sql))
                if cursor.description:
                    # Write header row
                    header = []
                    for f in cursor.description:
                        cell = WriteOnlyCell(ws, value=f[0])
                        cell.style = "readlonlyheaderstyle"
                        cell.comment = comment
                        header.append(cell)
                    ws.append(header)

                    # Add an auto-filter to the table
                    ws.auto_filter.ref = "A1:%s1048576" % get_column_letter(
                        len(header))

                # Write all output rows
                for result in cursor.fetchall():
                    ws.append(
                        [_getCellValue(i, request=request) for i in result])

            # Write the spreadsheet
            wb.save(out)
        finally:
            if conn:
                conn.close()
示例#2
0
def exportWorkbook(request):
    # Create a workbook
    wb = Workbook(write_only=True)

    # Create a named style for the header row
    headerstyle = NamedStyle(name="headerstyle")
    headerstyle.fill = PatternFill(fill_type="solid", fgColor="70c4f4")
    wb.add_named_style(headerstyle)
    readlonlyheaderstyle = NamedStyle(name="readlonlyheaderstyle")
    readlonlyheaderstyle.fill = PatternFill(fill_type="solid",
                                            fgColor="d0ebfb")
    wb.add_named_style(readlonlyheaderstyle)

    # Loop over all selected entity types
    exportConfig = {"anonymous": request.POST.get("anonymous", False)}
    ok = False
    for entity_name in request.POST.getlist("entities"):
        try:
            # Initialize
            (app_label, model_label) = entity_name.split(".")
            model = apps.get_model(app_label, model_label)
            # Verify access rights
            permname = get_permission_codename("change", model._meta)
            if not request.user.has_perm("%s.%s" % (app_label, permname)):
                continue

            # Never export some special administrative models
            if model in EXCLUDE_FROM_BULK_OPERATIONS:
                continue

            # Create sheet
            ok = True
            ws = wb.create_sheet(title=force_text(model._meta.verbose_name))

            # Build a list of fields and properties
            fields = []
            modelfields = []
            header = []
            source = False
            lastmodified = False
            owner = False
            comment = None
            try:
                # The admin model of the class can define some fields to exclude from the export
                exclude = data_site._registry[model].exclude
            except Exception:
                exclude = None
            for i in model._meta.fields:
                if i.name in ["lft", "rght", "lvl"]:
                    continue  # Skip some fields of HierarchyModel
                elif i.name == "source":
                    source = i  # Put the source field at the end
                elif i.name == "lastmodified":
                    lastmodified = i  # Put the last-modified field at the very end
                elif not (exclude and i.name in exclude):
                    fields.append(i.column)
                    modelfields.append(i)
                    cell = WriteOnlyCell(ws,
                                         value=force_text(
                                             i.verbose_name).title())
                    if i.editable:
                        cell.style = "headerstyle"
                        if isinstance(i, ForeignKey):
                            cell.comment = CellComment(
                                force_text(
                                    _("Values in this field must exist in the %s table"
                                      ) % force_text(i.remote_field.model.
                                                     _meta.verbose_name)),
                                "Author",
                            )
                        elif i.choices:
                            cell.comment = CellComment(
                                force_text(
                                    _("Accepted values are: %s") %
                                    ", ".join([c[0] for c in i.choices])),
                                "Author",
                            )
                    else:
                        cell.style = "readlonlyheaderstyle"
                        if not comment:
                            comment = CellComment(
                                force_text(_("Read only")),
                                "Author",
                                height=20,
                                width=80,
                            )
                        cell.comment = comment
                    header.append(cell)
                    if i.name == "owner":
                        owner = True
            if hasattr(model, "propertyFields"):
                if callable(model.propertyFields):
                    props = model.propertyFields(request)
                else:
                    props = model.propertyFields
                for i in props:
                    if i.export:
                        fields.append(i.name)
                        cell = WriteOnlyCell(ws,
                                             value=force_text(
                                                 i.verbose_name).title())
                        if i.editable:
                            cell.style = "headerstyle"
                            if isinstance(i, ForeignKey):
                                cell.comment = CellComment(
                                    force_text(
                                        _("Values in this field must exist in the %s table"
                                          ) % force_text(i.remote_field.model.
                                                         _meta.verbose_name)),
                                    "Author",
                                )
                        elif i.choices:
                            cell.comment = CellComment(
                                force_text(
                                    _("Accepted values are: %s") %
                                    ", ".join([c[0] for c in i.choices])),
                                "Author",
                            )
                        else:
                            cell.style = "readlonlyheaderstyle"
                            if not comment:
                                comment = CellComment(
                                    force_text(_("Read only")),
                                    "Author",
                                    height=20,
                                    width=80,
                                )
                            cell.comment = comment
                        header.append(cell)
                        modelfields.append(i)
            if source:
                fields.append("source")
                cell = WriteOnlyCell(ws, value=force_text(_("source")).title())
                cell.style = "headerstyle"
                header.append(cell)
                modelfields.append(source)
            if lastmodified:
                fields.append("lastmodified")
                cell = WriteOnlyCell(ws,
                                     value=force_text(
                                         _("last modified")).title())
                cell.style = "readlonlyheaderstyle"
                if not comment:
                    comment = CellComment(force_text(_("Read only")),
                                          "Author",
                                          height=20,
                                          width=80)
                cell.comment = comment
                header.append(cell)
                modelfields.append(lastmodified)

            # Write a formatted header row
            ws.append(header)

            # Add an auto-filter to the table
            ws.auto_filter.ref = "A1:%s1048576" % get_column_letter(
                len(header))

            # Use the default manager
            if issubclass(model, HierarchyModel):
                model.rebuildHierarchy(database=request.database)
                query = (model.objects.all().using(request.database).order_by(
                    "lvl", "pk"))
            elif owner:
                # First export records with empty owner field
                query = (model.objects.all().using(request.database).order_by(
                    "-owner", "pk"))
            else:
                query = model.objects.all().using(
                    request.database).order_by("pk")

            # Special annotation of the export query
            if hasattr(model, "export_objects"):
                query = model.export_objects(query, request)

            # Loop over all records
            for rec in query.values_list(*fields):
                cells = []
                fld = 0
                for f in rec:
                    cells.append(
                        _getCellValue(f,
                                      field=modelfields[fld],
                                      exportConfig=exportConfig))
                    fld += 1
                ws.append(cells)
        except Exception:
            pass  # Silently ignore the error and move on to the next entity.

    # Not a single entity to export
    if not ok:
        raise Exception(_("Nothing to export"))

    # Write the excel from memory to a string and then to a HTTP response
    output = BytesIO()
    wb.save(output)
    response = HttpResponse(
        content_type=
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        content=output.getvalue(),
    )
    response["Content-Disposition"] = 'attachment; filename="frepple.xlsx"'
    response["Cache-Control"] = "no-cache, no-store"
    return response