export_xlsx_writer.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # -*- coding: utf-8 -*-
  2. import datetime
  3. import io
  4. from odoo.tools import pycompat
  5. from odoo.tools.translate import _
  6. from odoo.tools.misc import xlsxwriter
  7. from odoo.exceptions import UserError
  8. # 根据addons/web/controllers/main.py中的ExportXlsxWriter改编而来
  9. class ExportXlsxWriter:
  10. def __init__(self, headers, row_count=0):
  11. self.headers = headers
  12. self.output = io.BytesIO()
  13. self.workbook = xlsxwriter.Workbook(self.output, {'in_memory': True})
  14. self.base_style = self.workbook.add_format({'text_wrap': True})
  15. self.header_style = self.workbook.add_format(
  16. {'bold': True, 'align': 'center', 'valign': 'vcenter', 'bg_color': '#ADD8E6'})
  17. self.sum_style = self.workbook.add_format({'bold': True, 'align': 'center', 'valign': 'vcenter'})
  18. self.header_bold_style = self.workbook.add_format({'text_wrap': True, 'bold': True, 'bg_color': '#e9ecef'})
  19. # self.date_style = self.workbook.add_format({'text_wrap': True, 'num_format': 'yyyy-mm-dd'})
  20. # self.datetime_style = self.workbook.add_format({'text_wrap': True, 'num_format': 'yyyy-mm-dd hh:mm:ss'})
  21. self.worksheet = self.workbook.add_worksheet()
  22. self.value = False
  23. self._font_color_dic = {}
  24. self._background_color_dic = {}
  25. self._font_and_background_color_dic = {}
  26. if row_count > self.worksheet.xls_rowmax:
  27. raise UserError('行数%s,超过Excel允许的最大行数%s' % (row_count, self.worksheet.xls_rowmax))
  28. return
  29. def __enter__(self):
  30. self.write_header()
  31. return self
  32. def __exit__(self, exc_type, exc_value, exc_traceback):
  33. self.close()
  34. return
  35. def get_font_color(self, color):
  36. if not color:
  37. return None
  38. if color not in self._font_color_dic:
  39. style = self.workbook.add_format({'font_color': color}) # font_color: also can use color
  40. self._font_color_dic[color] = style
  41. return style
  42. return self._font_color_dic[color]
  43. def get_background_color(self, color):
  44. if not color:
  45. return None
  46. if color not in self._background_color_dic:
  47. style = self.workbook.add_format({'fg_color': color})
  48. self._background_color_dic[color] = style
  49. return style
  50. return self._background_color_dic[color]
  51. def get_font_and_background_color(self, font_color, background_color):
  52. if not font_color and not background_color:
  53. return None
  54. if not font_color:
  55. return self.get_background_color(background_color)
  56. if not background_color:
  57. return self.get_font_color(font_color)
  58. key = font_color + background_color
  59. if key not in self._font_and_background_color_dic:
  60. style = self.workbook.add_format({'font_color': font_color, 'fg_color': background_color})
  61. self._font_and_background_color_dic[key] = style
  62. return style
  63. return self._font_and_background_color_dic[key]
  64. def write_header(self):
  65. # Write main header
  66. for i, head_data in enumerate(self.headers):
  67. name = head_data[0]
  68. width = ExportXlsxWriter._get_width(head_data[1])
  69. self.write(0, i, name, self.header_style)
  70. self.worksheet.set_column(i, i, width)
  71. return
  72. @staticmethod
  73. def _get_width(width):
  74. return width * 30 / 220 # 30:around 220 pixels
  75. def close(self):
  76. self.workbook.close()
  77. with self.output:
  78. self.value = self.output.getvalue()
  79. return
  80. def write(self, row, column, cell_value, style=None):
  81. self.worksheet.write(row, column, cell_value, style)
  82. return
  83. def write_cell(self, row, column, cell_value, cell_style=None):
  84. cell_style = cell_style if cell_style else self.base_style
  85. if isinstance(cell_value, str):
  86. if len(cell_value) > self.worksheet.xls_strmax:
  87. cell_value = _(
  88. "The content of this cell is too long for an XLSX file (more than %s characters). Please use the CSV format for this export.",
  89. self.worksheet.xls_strmax)
  90. else:
  91. cell_value = cell_value.replace("\r", " ")
  92. self.write(row, column, cell_value, cell_style)
  93. return