excel_export.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. from odoo import http
  2. from odoo.http import serialize_exception, request, content_disposition
  3. from odoo.utils.export_xlsx_writer import ExportXlsxWriter
  4. import json
  5. import operator
  6. CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  7. class ExcelExport(http.Controller):
  8. @http.route('/web/export/analyse/xlsx', type='http', auth="user")
  9. # @serialize_exception
  10. def export_excel(self, data, token):
  11. params = json.loads(data)
  12. model_name = operator.itemgetter('model')(params)
  13. model = request.env[model_name]
  14. file_name = ExcelExport._get_file_name(model._description)
  15. result = model.get_result(request.session.uid)
  16. head = result[0]
  17. contents = result[1]
  18. sum_row = result[2]
  19. response_data = ExcelExport._from_data(head, contents, sum_row)
  20. return request.make_response(response_data,
  21. headers=[('Content-Disposition', content_disposition(file_name)),
  22. ('Content-Type', CONTENT_TYPE)],
  23. cookies={'fileToken': token})
  24. @staticmethod
  25. def _get_file_name(model_description):
  26. if ':' in model_description:
  27. name = model_description.split(':')[1]
  28. elif ':' in model_description:
  29. name = model_description.split(':')[1]
  30. else:
  31. name = model_description
  32. return '%s分析.xlsx' % name
  33. @staticmethod
  34. def _from_data(head, rows, sum_row):
  35. freeze_column_count = ExcelExport._get_freeze_column_count(head)
  36. number_column_index_list = ExcelExport._get_number_column_index_list(sum_row)
  37. with ExportXlsxWriter(head, len(rows)) as xlsx_writer:
  38. for row_index, row in enumerate(rows):
  39. for cell_index, data in enumerate(row):
  40. cell_value = data[0]
  41. color = ExcelExport._get_cell_color(data, xlsx_writer, cell_index, freeze_column_count)
  42. if cell_index in number_column_index_list and cell_value:
  43. cell_value = ExcelExport._get_number(cell_value)
  44. xlsx_writer.worksheet.write_number(row_index + 1, cell_index, cell_value, color)
  45. else:
  46. xlsx_writer.write_cell(row_index + 1, cell_index, cell_value, color)
  47. ExcelExport._write_sum_row(row_index, sum_row, xlsx_writer)
  48. xlsx_writer.worksheet.freeze_panes(1, freeze_column_count)
  49. return xlsx_writer.value
  50. @staticmethod
  51. def _write_sum_row(row_index, sum_row, xlsx_writer):
  52. if sum_row:
  53. row_index += 2
  54. diff = 0
  55. for cell_index, data in enumerate(sum_row):
  56. cell_value, cell_span = data
  57. if cell_span > 1:
  58. xlsx_writer.worksheet.merge_range(row_index, cell_index + diff, row_index,
  59. cell_index + diff + cell_span - 1, cell_value,
  60. xlsx_writer.sum_style)
  61. diff += cell_span - 1
  62. else:
  63. xlsx_writer.write_cell(row_index, cell_index + diff, cell_value)
  64. @staticmethod
  65. def _get_cell_color(data, xlsx_writer, cell_index, freeze_column_count):
  66. if freeze_column_count and cell_index < freeze_column_count:
  67. return xlsx_writer.get_background_color('#FFC0CB')
  68. color = None
  69. if len(data) > 2:
  70. font_color = data[1]
  71. background_color = data[2]
  72. if font_color and background_color:
  73. color = xlsx_writer.get_font_and_background_color(font_color, background_color)
  74. elif font_color:
  75. color = xlsx_writer.get_font_color(font_color)
  76. else:
  77. color = xlsx_writer.get_background_color(background_color)
  78. return color
  79. @staticmethod
  80. def _get_freeze_column_count(head):
  81. is_find = False
  82. for index, data in enumerate(head):
  83. if not is_find and data[2] == -1:
  84. is_find = True
  85. if is_find:
  86. return index
  87. return 0
  88. @staticmethod
  89. def _get_number_column_index_list(sum_row):
  90. _list = []
  91. diff = 0
  92. for index, data in enumerate(sum_row):
  93. if data[1] > 1:
  94. diff += data[1] - 1
  95. if isinstance(data[0], (int, float)):
  96. _list.append(index + diff)
  97. return _list
  98. @staticmethod
  99. def _get_number(str_value):
  100. if '.' in str_value:
  101. return float(str_value)
  102. return int(str_value)