XLSX Export vereinheitlicht.
Spieler Hanchanlisten können nun als XLSX exportiert werden. Anpassungen in den Einstellungen für die parametisierten Kyu/Dan Berechnung.
This commit is contained in:
@@ -12,6 +12,7 @@ from django.utils.translation import ugettext as _
|
||||
from django.views import generic
|
||||
|
||||
from events.mixins import EventDetailMixin
|
||||
from kasu import xlsx
|
||||
from . import forms, models
|
||||
from .mixins import MahjongMixin
|
||||
|
||||
@@ -28,56 +29,6 @@ KYU_DAN_ORDER = { # map sort URL args to Django ORM order_by args
|
||||
'-username': ('-user__username',)
|
||||
}
|
||||
|
||||
def getattr_recursive(obj, attr_string):
|
||||
attr_list = attr_string.split('.')
|
||||
return_value=None
|
||||
for attr in attr_list:
|
||||
print("Obj:", obj,'Attr:', attr)
|
||||
return_value = getattr(obj, attr)
|
||||
obj = return_value
|
||||
return return_value
|
||||
|
||||
def generate_sheet(workbook, title, columns_settings, object_list):
|
||||
row = 1
|
||||
ws = workbook.create_sheet()
|
||||
ws.title = title
|
||||
ws.syncHorizontal = True
|
||||
ws.filterMode = True
|
||||
|
||||
# setup print orientation
|
||||
ws.page_setup.orientation = ws.ORIENTATION_PORTRAIT
|
||||
ws.page_setup.paperSize = ws.PAPERSIZE_A4
|
||||
ws.page_setup.fitToWidth = True
|
||||
ws.print_options.horizontalCentered = True
|
||||
|
||||
# setup page header
|
||||
ws.oddHeader.left.text = title
|
||||
ws.oddHeader.left.size = 14
|
||||
ws.oddHeader.left.font = "Amerika Sans"
|
||||
ws.oddHeader.left.color = "000000"
|
||||
|
||||
ws.oddHeader.right.text = str(date.today())
|
||||
ws.oddHeader.right.size = 14
|
||||
ws.oddHeader.right.font = "Amerika Sans"
|
||||
ws.oddHeader.right.color = "000000"
|
||||
|
||||
# write table header
|
||||
for column, data in enumerate(columns_settings, 1):
|
||||
cell = ws.cell(column=column, row=row, value=data['title'])
|
||||
cell.style = 'heading'
|
||||
|
||||
# write the table content
|
||||
for line in object_list:
|
||||
row += 1
|
||||
for column, settings in enumerate(columns_settings, 1):
|
||||
cell = ws.cell(column=column, row=row, value=getattr_recursive(line, settings['attr']))
|
||||
cell.style = settings['style']
|
||||
|
||||
# set column widths
|
||||
for settings in columns_settings:
|
||||
ws.column_dimensions[settings['col']].width = settings['width']
|
||||
|
||||
|
||||
|
||||
class DeleteHanchan(EventDetailMixin, PermissionRequiredMixin,
|
||||
generic.DeleteView):
|
||||
@@ -235,48 +186,67 @@ class PlayerScore(LoginRequiredMixin, generic.ListView):
|
||||
return context
|
||||
|
||||
def get_xlsx(self, request, *args, **kwargs):
|
||||
from management.commands.export_ranking import geneate_excel
|
||||
self.object_list = self.get_queryset()
|
||||
allow_empty = self.get_allow_empty()
|
||||
response = django.http.HttpResponse(
|
||||
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
response[
|
||||
'Content-Disposition'] = 'attachment; filename="{xlsx_filename}"'.format(xlsx_filename=self.xlsx_filename)
|
||||
xlxs_workbook = geneate_excel()
|
||||
print(self.xlsx_columns)
|
||||
generate_sheet(xlxs_workbook,
|
||||
title=self.xlsx_filename,
|
||||
columns_settings=self.xlsx_columns,
|
||||
object_list=self.object_list
|
||||
)
|
||||
xlxs_workbook.create_sheet()
|
||||
response['Content-Disposition'] = 'attachment; ' \
|
||||
'filename="{xlsx_filename}"'.format(
|
||||
xlsx_filename=self.xlsx_filename)
|
||||
xlxs_workbook = xlsx.Workbook()
|
||||
xlxs_workbook.generate_sheet(
|
||||
title=self.xlsx_filename.split('.')[0],
|
||||
columns_settings=self.xlsx_columns,
|
||||
object_list=self.object_list
|
||||
)
|
||||
xlxs_workbook.save(response)
|
||||
return response
|
||||
|
||||
|
||||
class PlayerDanScore(PlayerScore):
|
||||
template_name = 'mahjong_ranking/player_dan_score.html'
|
||||
xlsx_columns = (
|
||||
{'col': 'A', 'title': 'Beginn', 'attr': 'start', 'style': 'date', 'width': 14},
|
||||
{'col': 'B', 'title': 'Platzierung', 'attr': 'placement', 'style': 'int', 'width': 8},
|
||||
{'col': 'C', 'title': 'Spieler 1', 'attr': 'player1.username', 'style': 'content', 'width': 8},
|
||||
{'col': 'D', 'title': 'Punkte', 'attr': 'player1_game_score', 'style': 'int', 'width': 8},
|
||||
{'col': 'E', 'title': 'Spieler 2', 'attr': 'player2.username', 'style': 'content', 'width': 8},
|
||||
{'col': 'F', 'title': 'Punkte', 'attr': 'player2_game_score', 'style': 'int', 'width': 8},
|
||||
{'col': 'G', 'title': 'Spieler 3', 'attr': 'player3.username', 'style': 'content', 'width': 8},
|
||||
{'col': 'H', 'title': 'Punkte', 'attr': 'player3_game_score', 'style': 'int', 'width': 8},
|
||||
{'col': 'I', 'title': 'Spieler 4', 'attr': 'player4.username', 'style': 'content', 'width': 8},
|
||||
{'col': 'J', 'title': 'Punkte', 'attr': 'player4_game_score', 'style': 'int', 'width': 8},
|
||||
{'col': 'K', 'title': 'Dan Punkte', 'attr': 'dan_points', 'style': 'int', 'width': 8},
|
||||
{'col': 'L', 'title': 'Anmerkung', 'attr': 'comment', 'style': 'content', 'width': 8},
|
||||
)
|
||||
|
||||
def get_queryset(self):
|
||||
kyu_dan_ranking = models.KyuDanRanking.objects.get(user=self.user)
|
||||
self.xlsx_filename = "{username}_dan_score.xlsx".format(
|
||||
username=self.user.username)
|
||||
return models.Hanchan.objects.dan_hanchans(user=self.user,
|
||||
since=kyu_dan_ranking.legacy_date)
|
||||
self.kyu_dan_ranking = models.KyuDanRanking.objects.get(user=self.user)
|
||||
return models.Hanchan.objects.dan_hanchans(
|
||||
user=self.user,
|
||||
since=self.kyu_dan_ranking.legacy_date)
|
||||
|
||||
@property
|
||||
def xlsx_columns(self):
|
||||
return (
|
||||
{'col': 'A', 'title': 'Beginn', 'attr': 'start',
|
||||
'style': 'Date Time',
|
||||
'width': 14, 'footer': self.kyu_dan_ranking.legacy_date},
|
||||
{'col': 'B', 'title': 'Termin', 'attr': 'event.name',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'C', 'title': 'Platzierung', 'attr': 'placement',
|
||||
'style': 'Integer', 'width': 11},
|
||||
{'col': 'D', 'title': 'Spieler 1', 'attr': 'player1.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'E', 'title': 'Punkte', 'attr': 'player1_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'F', 'title': 'Spieler 2', 'attr': 'player2.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'G', 'title': 'Punkte', 'attr': 'player2_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'H', 'title': 'Spieler 3', 'attr': 'player3.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'I', 'title': 'Punkte', 'attr': 'player3_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'J', 'title': 'Spieler 4', 'attr': 'player4.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'K', 'title': 'Punkte', 'attr': 'player4_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'L', 'title': 'Dan Punkte', 'attr': 'dan_points',
|
||||
'style': 'Integer', 'width': 12,
|
||||
'footer': self.kyu_dan_ranking.legacy_dan_points},
|
||||
{'col': 'M', 'title': 'Anmerkung', 'attr': 'comment',
|
||||
'style': 'Content', 'width': 20, 'footer': 'Legacy Dan Punkte'},
|
||||
)
|
||||
|
||||
@property
|
||||
def xlsx_filename(self):
|
||||
return "{username}_dan_score.xlsx".format(username=self.user.username)
|
||||
|
||||
|
||||
class PlayerInvalidScore(PlayerScore):
|
||||
@@ -292,9 +262,47 @@ class PlayerKyuScore(PlayerScore):
|
||||
template_name = 'mahjong_ranking/player_kyu_score.html'
|
||||
|
||||
def get_queryset(self):
|
||||
self.xlsx_filename = "{username}_kyu_score.xlsx".format(
|
||||
username=self.user.username)
|
||||
return models.Hanchan.objects.kyu_hanchans(self.user)
|
||||
self.kyu_dan_ranking = models.KyuDanRanking.objects.get(user=self.user)
|
||||
return models.Hanchan.objects.kyu_hanchans(
|
||||
user=self.user,
|
||||
since=self.kyu_dan_ranking.legacy_date)
|
||||
|
||||
@property
|
||||
def xlsx_columns(self):
|
||||
return (
|
||||
{'col': 'A', 'title': 'Beginn', 'attr': 'start',
|
||||
'style': 'Date Time',
|
||||
'width': 14, 'footer': self.kyu_dan_ranking.legacy_date},
|
||||
{'col': 'B', 'title': 'Termin', 'attr': 'event.name',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'C', 'title': 'Platzierung', 'attr': 'placement',
|
||||
'style': 'Integer', 'width': 11},
|
||||
{'col': 'D', 'title': 'Spieler 1', 'attr': 'player1.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'E', 'title': 'Punkte', 'attr': 'player1_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'F', 'title': 'Spieler 2', 'attr': 'player2.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'G', 'title': 'Punkte', 'attr': 'player2_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'H', 'title': 'Spieler 3', 'attr': 'player3.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'I', 'title': 'Punkte', 'attr': 'player3_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'J', 'title': 'Spieler 4', 'attr': 'player4.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'K', 'title': 'Punkte', 'attr': 'player4_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'L', 'title': 'Kyū Punkte', 'attr': 'kyu_points',
|
||||
'style': 'Integer', 'width': 12,
|
||||
'footer': self.kyu_dan_ranking.legacy_kyu_points},
|
||||
{'col': 'M', 'title': 'Anmerkung', 'attr': 'comment',
|
||||
'style': 'Content', 'width': 24, 'footer': 'Legacy Kyū Punkte'},
|
||||
)
|
||||
|
||||
@property
|
||||
def xlsx_filename(self):
|
||||
return "{username}_kyu_score.xlsx".format(username=self.user.username)
|
||||
|
||||
|
||||
class PlayerLadderScore(PlayerScore):
|
||||
@@ -311,10 +319,44 @@ class PlayerLadderScore(PlayerScore):
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
self.season = int(self.request.GET.get('season', date.today().year))
|
||||
self.xlsx_filename = "{username}_ladder ({season}).xlsx".format(
|
||||
username=self.user.username, season=self.season)
|
||||
hanchan_list = models.Hanchan.objects.season_hanchans(
|
||||
user=self.user,
|
||||
season=self.season
|
||||
)
|
||||
return hanchan_list
|
||||
|
||||
@property
|
||||
def xlsx_columns(self):
|
||||
return (
|
||||
{'col': 'A', 'title': 'Beginn', 'attr': 'start',
|
||||
'style': 'Date Time', 'width': 14},
|
||||
{'col': 'B', 'title': 'Termin', 'attr': 'event.name',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'C', 'title': 'Platzierung', 'attr': 'placement',
|
||||
'style': 'Integer', 'width': 11},
|
||||
{'col': 'D', 'title': 'Spieler 1', 'attr': 'player1.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'E', 'title': 'Punkte', 'attr': 'player1_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'F', 'title': 'Spieler 2', 'attr': 'player2.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'G', 'title': 'Punkte', 'attr': 'player2_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'H', 'title': 'Spieler 3', 'attr': 'player3.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'I', 'title': 'Punkte', 'attr': 'player3_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'J', 'title': 'Spieler 4', 'attr': 'player4.username',
|
||||
'style': 'Content', 'width': 16},
|
||||
{'col': 'K', 'title': 'Punkte', 'attr': 'player4_game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
{'col': 'L', 'title': 'Punkte', 'attr': 'game_score',
|
||||
'style': 'Integer', 'width': 8},
|
||||
)
|
||||
|
||||
@property
|
||||
def xlsx_filename(self):
|
||||
return "{username}_ladder_score_{season}.xlsx".format(
|
||||
username=self.user.username,
|
||||
season=self.season
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user