首页 > 解决方案 > 在 Django 中使用 openpyxl 将数据导出到 Excel

问题描述

我正在尝试使用 openpyxl 包将数据导出到 excel,但 django 抛出错误“utf-8”编解码器无法解码位置 3 的字节 0xae:无效的起始字节。你传入了 b'{\x1ah\xae' (<class 'bytes'>)。

    class FeedbackExportView(View):

         def get(self, request):
              feedback_queryset = Feedback.objects.all()
              response = HttpResponse(
                         content_type='application/vnd.openxmlformats- 
                         officedocument.spreadsheetml.sheet',
                         )
              response['Content-Disposition'] = 'attachment; filename={date}- 
                                                 feedback.xlsx'.format(
                                   date=datetime.datetime.now().strftime('%Y-%m-%d'),
                                    )
             workbook = Workbook()
             worksheet = workbook.active
             worksheet.title = 'Feedback'
             columns = ['candidate email', 'candidate Name', 'vacancy', 'Interview 
                         Round', 'Interviewer', 'Recommendation']

             row_num = 1
            for col_num, column_title in enumerate(columns, 1):
                  cell = worksheet.cell(row=row_num, column=col_num)
                  cell.value = column_title

           for feedback in feedback_queryset:
              row_num += 1
              row = [
               feedback.candidate.user.email,
               feedback.candidate.user.full_name,
               feedback.candidate.vacancy.title,
               feedback.interview.interview_round,
               feedback.interview.interviewer_id.all()[0].full_name,
               feedback.selection_recommendation,
              ]

          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

回溯(最近一次通话最后):文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/utils/encoding.py”,第 62 行,在 force_str 中= str(s, encoding, errors) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xae in position 3: invalid start byte

在处理上述异常的过程中,又出现了一个异常:

回溯(最近一次通话):文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/core/handlers/exception.py”,第 47 行,在内部响应 = get_response(request)

文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/core/handlers/base.py”,第 181 行,在 _get_response callback_args, **callback_kwargs)

文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/views/generic/base.py”,第 70 行,在视图中返回 self.dispatch(request, *args, **kwargs)

文件“/Users/chinmayagrawal/Desktop/interview-management-system/Interview_management/interview/views.py”,第 187 行,在调度 self.get_interview()

文件“/Users/chinmayagrawal/Desktop/interview-management-system/Interview_management/interview/views.py”,第 191 行,在 get_interview interview = force_text(

文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/utils/encoding.py”,第 115 行,在 force_text 返回 force_str(s, encoding, strings_only,错误)

文件“/Users/chinmayagrawal/Desktop/interview-management-system/venv/lib/python3.8/site-packages/django/utils/encoding.py”,第 66 行,在 force_str 中引发 DjangoUnicodeDecodeError(s, *e.args )

django.utils.encoding.DjangoUnicodeDecodeError:'utf-8'编解码器无法解码位置 3 的字节 0xae:无效的起始字节。您传入 b'{\x1ah\xae' (<class 'bytes'>) [09/Sep/2021 12:32:14] "GET /interview/feedback/export/HTTP/1.1" 500 82672

  class FeedbackView(LoginRequiredMixin, CreateView):
"""
View to create feedbacks for candidate and also duplicate feedback
"""
model = Feedback
template_name = 'interview/feedback.html'
form_class = FeedbackForm

def get_initial(self):
    initial = super().get_initial()
    initial.update({
        'email': self.applicant_email,
        'first_name': self.applicant_first_name,
        'last_name': self.applicant_last_name,
        'vacancy': self.applicant_vacancy
    })
    return initial

def dispatch(self, request, *args, **kwargs):
    self.get_interview()
    return super().dispatch(request, *args, **kwargs)

def get_interview(self):
    interview = force_text(
        urlsafe_base64_decode(self.kwargs.get('uidb64')))
    obj = Interview.objects.get(id=int(interview))
    self.obj = obj
    self.interviewer = obj.interviewer_id.all()[0]
    self.applicant_email = obj.candidate_id.user.email
    self.applicant_first_name = obj.candidate_id.user.first_name
    self.applicant_last_name = obj.candidate_id.user.last_name
    self.applicant_vacancy = obj.candidate_id.vacancy

def feedback_duplicate(self, applicant, form):
    feedback_duplicate = FeedbackDuplicate.objects.create(candidate=applicant, interview=self.obj,
                                                          interview_feedback=form.instance.interview_feedback,
                                                          technical_knowledge=form.instance.technical_knowledge,
                                                          education=form.instance.education,
                                                          problem_solving=form.instance.problem_solving,
                                                          learning_ability=form.instance.learning_ability,
                                                          diligence=form.instance.diligence,
                                                          confidence_level=form.instance.confidence_level,
                                                          communication_skills=form.instance.communication_skills,
                                                          listening_skills=form.instance.listening_skills,
                                                          strength=form.instance.strength,
                                                          weakness=form.instance.weakness,
                                                          selection_recommendation=form.instance.selection_recommendation)
    current_site = get_current_site(self.request).domain
    relative_link = reverse('interview:duplicate-feedback-update', kwargs={"pk": feedback_duplicate.id})
    absurl = 'http://' + current_site + relative_link
    applicant = Applicant.objects.get(id=feedback_duplicate.candidate.id)
    applicant.candidate_feedback = absurl
    applicant.save()

def form_valid(self, form):
    if self.request.user == self.interviewer:
        candidate_email = form.cleaned_data.get('email')
        applicant = Applicant.objects.get(user__email=candidate_email)
        form.instance.interview = self.obj
        form.instance.candidate = applicant
        self.object = form.save()
        self.email(self.obj)
        self.feedback_duplicate(applicant, form)
        messages.success(self.request, 'Feedback Submitted Successfully')
        return super(FeedbackView, self).form_valid(form)
    else:
        messages.error(self.request, 'You are not authorized to submit feedback for this candidate')
        return render(self.request, self.template_name, {'form': self.form_class})

def email(self, interview):
    message = f"""
           <p>
           The Interview feedback of <strong>{interview.candidate_id.user.full_name}</strong> has been 
           submitted by <strong>{interview.interviewer_id.all()[0].full_name}</strong>.
           </p>
    """
    feedback_data = {'email_body': message, 'to_email': config('DEFAULT_FROM_EMAIL'),
                     'email_subject': 'Candidate Feedback Submitted'}
    sched.feedback_confirm_email_schedule(feedback_data)

def get_success_url(self):
    return reverse_lazy('interview:feedback', kwargs={'uidb64': self.kwargs.get('uidb64')})


         

标签: python-3.xdjango

解决方案


推荐阅读