django-import-export如何格式化导出的Excel单元格?

时间:2018-11-01 00:48:39

标签: django excel django-import-export

有什么方法可以格式化导出的Excel文件?当我导出文件时,该列太小而无法容纳单词。我对此很陌生,因此将不胜感激。

Exported excel file looks something like this, the title cell is too small to fit the words.

如果django-import-export无法做到这一点,那么还有其他方法可以将数据库信息导出为ex​​cel并可以格式化文件吗?

实际上有人问过类似的问题,但没有答案:

Is there a way to manage the column/cell widths when exporting to Excel with django-import-export?

我在admin.py中的一些代码

class LogResource(resources.ModelResource):
    date = Field(attribute='date', column_name='Date')
    dtime = Field(attribute='dtime', column_name='Departure Time')
    pilot = Field(attribute='pilot', column_name='Pilot')
    cpilot = Field(attribute='cpilot', column_name='Co-Pilot')
    purpose = Field(attribute='purpose', column_name='Purpose of Flight')
    others = Field(attribute='others', column_name='Others')

    class Meta:
        model=Log
        exclude=('id',)


class LogAdmin(ExportActionModelAdmin, admin.ModelAdmin):
    resource_class = LogResource
    list_display = ('date', 'dtime', 'purpose', 'pilot', 'cpilot')
    list_filter = ('date', 'purpose', 'pilot')

在views.py

def logentry_form_submission(request):
    date = request.POST["date"]
    dtime = request.POST["dtime"]
    pilot = request.POST["pilot"]
    cpilot = request.POST["cpilot"]
    purpose = request.POST["purpose"]
    others = request.POST["others"]

    log_info = Log(date=date, dtime=dtime, pilot=pilot, cpilot=cpilot,         
    purpose=purpose, others=others)
    log_info.save()
    return render(request, 'myhtml/logentry_form_submission.html')

由于我在线学习了所有内容,因此我的代码有点混乱,请随时改进我的代码。

1 个答案:

答案 0 :(得分:0)

没有官方的方法。我可以通过以下方法解决此问题:

  • 注册自己的tablib格式
  • 定义每个资源的格式
  • 将格式化程序回调从资源类传递到tablib导出代码

注册您自己的tablib格式:

from tablib.formats import registry
from tablib.formats._xlsx import XLSXFormat
class FormattedXLSX(XLSXFormat):
    @classmethod
    def export_set(cls, dataset, freeze_panes=True, formatter=None):
        """Returns XLSX representation of Dataset."""
        wb = Workbook()
        ws = wb.worksheets[0]
        ws.title = dataset.title if dataset.title else "Tablib Dataset"

        cls.dset_sheet(dataset, ws, freeze_panes=freeze_panes)

        ### Just added this lines to original code
        if formatter:
            formatter(ws)
        ###

        stream = BytesIO()
        wb.save(stream)
        return stream.getvalue()


registry.register("xlsx", FormattedXLSX())

调整资源类中的列宽:

class OrderResource(resources.ModelResource):
    @staticmethod
    def formatter(ws):
        ws.column_dimensions["B"].width = 15
        ws.column_dimensions["C"].width = 35
        ws.column_dimensions["D"].width = 12
        ws.column_dimensions["F"].width = 18

    class Meta:
        model = OrderFull

现在,我们需要以某种方式将其传递给tablib。看一下源代码: https://github.com/django-import-export/django-import-export/blob/2.0.2/import_export/admin.py#L461 您可以覆盖此方法,并将export_data = file_format.export_data(data)更改为export_data = file_format.export_data(data, resource_class.formatter)(未测试)。

由于我以不同的方式使用它(没有管理员集成),所以我可以提供一些不同的实现,但是受到原始ExportMixin代码的启发。

class ImportExportView(APIView):
    # ...
    def get(self, request, **kwargs):
        dataset = self.resource().export(self.queryset.all())
        # Inject formatter function from resource
        xslx = XLSX().export_data(dataset=dataset, formatter=self.resource.formatter)

        response = HttpResponse(
            content=xslx,
            content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        )
        response["Content-Disposition"] = f'attachment; filename="{self.filename}"'
        return response