Django导出Excel保存文件在服务器中(芹菜+ rabbitmq)

发布于 2025-01-30 01:21:31 字数 2616 浏览 2 评论 0原文

我有一个Django视图,该视图导出Excel文件并在文件准备就绪时提示下载对话框。我正在安装芹菜和兔子,以使此任务成为背景任务。这意味着不会提示excel文件下载,但是我想将其保存在计算机中的某个地方,因此用户稍后可以转到页面并下载它。

示例:

转到列表页面 - >单击导出 - >收到一条消息:“您的文件很快就会准备就绪” - >用户转到“下载”页面 - >在列表中找到文件 - >点击下载。

因此,我现在的过程是创建一个新模型:

class Export(models.Model):
    dossier = models.ForeignKey(
        Dossier,
        related_name="Export",
        on_delete=models.CASCADE,
        default=None,
        editable=False,
    )
    timestamp = models.DateTimeField(auto_now_add=True, editable=False)
    file = models.FileField(
        upload_to=get_rapport_filename, verbose_name="Fichiers Excel"
    )

    def __str__(self):
        return "%s - %s" % (self.dossier, self.timestamp)

    class Meta:
        verbose_name = "Excel Report"
        verbose_name_plural = "Excel Reports"

这是我生成excel文件的代码:

@shared_task
def export_dossiers_factures(request):
    dossier_queryset = Dossier.objects.filter(status_admin="Facturé")
    today = str(date.today())
    response = HttpResponse(
        content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    )
    response["Content-Disposition"] = (
        "attachment; filename=" + today + "-dossiers_factures.xlsx"
    )
    workbook = Workbook()

    # Get active worksheet/tab
    worksheet = workbook.active
    worksheet.title = "Dossiers facturés"

    # Define the titles for columns
    columns = [
        "Numéro",
        "Créé le",
        "Assurance",
        "Prestataire",
        "Matricule",
        "N° de BL",
        "N° de Facture",
        "Date de mise à jour",
    ]

    row_num = 1

    # Assign the titles for each cell of the header
    for col_num, column_title in enumerate(columns, 1):
        cell = worksheet.cell(row=row_num, column=col_num)
        cell.value = column_title

    # Iterate through all movies
    for dossier in dossier_queryset:
        row_num += 1

        # Define the data for each cell in the row
        row = [
            dossier.numero,
            str(dossier.date_posted)[:10],
            dossier.assurance.name,
            dossier.created_by.user.username,
            dossier.matricule,
            dossier.bl,
            dossier.invoice,
            str(dossier.date_updated)[:10],
        ]

        # Assign the data for each cell of the row
        for col_num, cell_value in enumerate(row, 1):
            cell = worksheet.cell(row=row_num, column=col_num)
            cell.value = cell_value

    workbook.save(response)

    return response

我想通过将文件保存在某个地方并创建指向该文件的对象来替换返回响应。

I have a Django view that exports an Excel File and prompts a Download Dialog when the file is ready. I am installing Celery and RabbitMQ to make this task a background task. This means that the excel file will not be prompted to be downloaded, but I would like to save it somewhere in the machine, so the user can later go to a page and download it.

Example:

Go to List page -> Click on Export -> Get a message: "Your file will be ready soon" -> User goes to "Downloads" Page -> Finds the file in a list -> Clicks to download.

So the process for me now is to create a new model:

class Export(models.Model):
    dossier = models.ForeignKey(
        Dossier,
        related_name="Export",
        on_delete=models.CASCADE,
        default=None,
        editable=False,
    )
    timestamp = models.DateTimeField(auto_now_add=True, editable=False)
    file = models.FileField(
        upload_to=get_rapport_filename, verbose_name="Fichiers Excel"
    )

    def __str__(self):
        return "%s - %s" % (self.dossier, self.timestamp)

    class Meta:
        verbose_name = "Excel Report"
        verbose_name_plural = "Excel Reports"

And this is the code I have that generates the Excel file:

@shared_task
def export_dossiers_factures(request):
    dossier_queryset = Dossier.objects.filter(status_admin="Facturé")
    today = str(date.today())
    response = HttpResponse(
        content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    )
    response["Content-Disposition"] = (
        "attachment; filename=" + today + "-dossiers_factures.xlsx"
    )
    workbook = Workbook()

    # Get active worksheet/tab
    worksheet = workbook.active
    worksheet.title = "Dossiers facturés"

    # Define the titles for columns
    columns = [
        "Numéro",
        "Créé le",
        "Assurance",
        "Prestataire",
        "Matricule",
        "N° de BL",
        "N° de Facture",
        "Date de mise à jour",
    ]

    row_num = 1

    # Assign the titles for each cell of the header
    for col_num, column_title in enumerate(columns, 1):
        cell = worksheet.cell(row=row_num, column=col_num)
        cell.value = column_title

    # Iterate through all movies
    for dossier in dossier_queryset:
        row_num += 1

        # Define the data for each cell in the row
        row = [
            dossier.numero,
            str(dossier.date_posted)[:10],
            dossier.assurance.name,
            dossier.created_by.user.username,
            dossier.matricule,
            dossier.bl,
            dossier.invoice,
            str(dossier.date_updated)[:10],
        ]

        # Assign the data for each cell of the row
        for col_num, cell_value in enumerate(row, 1):
            cell = worksheet.cell(row=row_num, column=col_num)
            cell.value = cell_value

    workbook.save(response)

    return response

I want to replace return response, by soomething that saves the file somewhere and creates an object pointing to that file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

(り薆情海 2025-02-06 01:21:31

我做的与您大致相同的事情,我这样做了:

首先,我创建文件并写下我想要的任何东西,因此,在您的情况下,类似的东西:

filepath = f'/filepath_to/{today}-dossiers_factures.xlsx'
workbook = Workbook(filepath)
... # Whatever you want to do with your file

一旦创建了文件,您就有Juste拥有要使用FileRePonse获取文件:

response = FileResponse(open(filepath, 'rb'))
response['Content-Disposition'] = f"attachment; filename={today}-dossiers_factures.xlsx"
return response

因此,在这种情况下,您下载了已存储在您放入的地方的文件,而不仅仅是创建文件并返回文件。

希望我了解您想要的东西,这回答了您的问题:)

I did approximately the same thing as you, and I did it that way :

First, I create my file and write whatever I want in it, so in your case, something like that :

filepath = f'/filepath_to/{today}-dossiers_factures.xlsx'
workbook = Workbook(filepath)
... # Whatever you want to do with your file

And once you have your file created, you juste have to get your file with a FileReponse :

response = FileResponse(open(filepath, 'rb'))
response['Content-Disposition'] = f"attachment; filename={today}-dossiers_factures.xlsx"
return response

So in this case, you download the file which has been stored in the place you put it in, instead of just creating a file and returning it.

Hope I understood what you wanted and that answers your question :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文