diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index fb69c52daaa1e440b2c48f3301bdd7f8700364ac..76854a7912a16eb62eb253fa9d8178d25e295f56 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -9,11 +9,13 @@ from sqlalchemy.orm import joinedload, aliased
 from sqlalchemy.orm.query import Query
 from sqlalchemy.dialects.postgresql import insert as pgsql_insert
 from typing import Any, List, Tuple, Optional, Sequence, Dict
+import urllib.parse
 import werkzeug.exceptions
 import wtforms
 
 import mo
 from mo.csv import FileFormat
+import mo.config as config
 import mo.db as db
 from mo.imports import ImportType, create_import
 import mo.jobs.submit
@@ -435,9 +437,11 @@ def org_contest_import(id: int):
 
 @app.route('/org/contest/c/<int:id>/ucastnici', methods=('GET', 'POST'))
 @app.route('/org/contest/c/<int:id>/site/<int:site_id>/ucastnici', methods=('GET', 'POST'))
+@app.route('/org/contest/c/<int:id>/ucastnici/emails', endpoint="org_contest_list_emails")
+@app.route('/org/contest/c/<int:id>/site/<int:site_id>/ucastnici/emails', endpoint="org_contest_list_emails")
 def org_contest_list(id: int, site_id: Optional[int] = None):
     contest, master_contest, site, rr = get_contest_site_rr(id, site_id, Right.view_contestants)
-    can_edit = rr.have_right(Right.manage_contest)
+    can_edit = rr.have_right(Right.manage_contest) and request.endpoint != 'org_contest_list_emails'
     format = request.args.get('format', "")
 
     filter = ParticipantsFilterForm(request.args)
@@ -458,14 +462,21 @@ def org_contest_list(id: int, site_id: Optional[int] = None):
             return redirect(request.url)
 
     if format == "":
-        # (count, query) = filter.apply_limits(query, pagesize=50)
-        count = db.get_count(query)
+        table = None
+        emails = None
+        mailto_link = None
+        if request.endpoint == 'org_contest_list_emails':
+            (emails, mailto_link) = get_contestant_emails(query)
+            count = len(emails)
+        else:
+            # (count, query) = filter.apply_limits(query, pagesize=50)
+            count = db.get_count(query)
+            table = make_contestant_table(query, add_checkbox=can_edit)
 
-        table = make_contestant_table(query, add_checkbox=can_edit)
         return render_template(
             'org_contest_list.html',
             contest=contest, site=site,
-            table=table,
+            table=table, emails=emails, mailto_link=mailto_link,
             filter=filter, count=count, action_form=action_form,
         )
     else:
@@ -570,6 +581,17 @@ def make_contestant_table(query: Query, add_checkbox: bool = False, add_contest_
     )
 
 
+def get_contestant_emails(query: Query, mailto_subject: str = '[OSMO] Zpráva pro účastníky') -> Tuple[List[str], str]:
+    users = [pion.user for (pion, _, _) in query.all()]
+    emails = [f'{u.first_name} {u.last_name} <{u.email}>' for u in users]
+    mailto_link = (
+        'mailto:' + urllib.parse.quote(config.MAIL_CONTACT, safe='@')
+        + '?subject=' + urllib.parse.quote(mailto_subject)
+        + '&bcc=' + ','.join([urllib.parse.quote(email, safe='@') for email in emails])
+    )
+    return (emails, mailto_link)
+
+
 @dataclass
 class SolutionContext:
     contest: db.Contest
diff --git a/mo/web/org_round.py b/mo/web/org_round.py
index 766193bef61cd865bc5c5ce7413758181e1df9ab..979093b19910c10f96cda26db941ac362ffd935c 100644
--- a/mo/web/org_round.py
+++ b/mo/web/org_round.py
@@ -16,7 +16,7 @@ import mo.imports
 from mo.rights import Right, RoundRights
 import mo.util
 from mo.web import app
-from mo.web.org_contest import ParticipantsActionForm, ParticipantsFilterForm, get_contestants_query, make_contestant_table, \
+from mo.web.org_contest import ParticipantsActionForm, ParticipantsFilterForm, get_contestant_emails, get_contestants_query, make_contestant_table, \
     generic_import, generic_batch_download, generic_batch_upload, generic_batch_points
 
 
@@ -338,8 +338,10 @@ def org_round_task_batch_points(round_id: int, task_id: int):
 
 
 @app.route('/org/contest/r/<int:id>/list', methods=('GET', 'POST'))
+@app.route('/org/contest/r/<int:id>/list/emails', endpoint="org_round_list_emails")
 def org_round_list(id: int):
-    round, master_round, r = get_round_rr(id, Right.view_contestants, True)
+    round, master_round, rr = get_round_rr(id, Right.view_contestants, True)
+    can_edit = rr.have_right(Right.manage_round) and request.endpoint != 'org_round_list_emails'
     format = request.args.get('format', "")
 
     filter = ParticipantsFilterForm(request.args)
@@ -352,20 +354,29 @@ def org_round_list(id: int):
         participation_state=filter.f_participation_state,
     )
 
-    action_form = ParticipantsActionForm()
-    if action_form.do_action(round=master_round, query=query):
-        # Action happened, redirect
-        return redirect(request.url)
+    action_form = None
+    if can_edit:
+        action_form = ParticipantsActionForm()
+        if action_form.do_action(round=master_round, query=query):
+            # Action happened, redirect
+            return redirect(request.url)
 
     if format == "":
-        (count, query) = filter.apply_limits(query, pagesize=50)
-        # count = db.get_count(query)
+        table = None
+        emails = None
+        mailto_link = None
+        if request.endpoint == 'org_round_list_emails':
+            (emails, mailto_link) = get_contestant_emails(query)
+            count = len(emails)
+        else:
+            (count, query) = filter.apply_limits(query, pagesize=50)
+            # count = db.get_count(query)
+            table = make_contestant_table(query, add_contest_column=True, add_checkbox=True)
 
-        table = make_contestant_table(query, add_contest_column=True, add_checkbox=True)
         return render_template(
             'org_round_list.html',
             round=round,
-            table=table,
+            table=table, emails=emails, mailto_link=mailto_link,
             filter=filter, count=count, action_form=action_form,
         )
     else:
diff --git a/mo/web/templates/org_contest_list.html b/mo/web/templates/org_contest_list.html
index 3f817038d356c560a25fe8d42ccd1100057b4eff..3e28dd3a6a3a88db5a9035c7e25b08c7b3287841 100644
--- a/mo/web/templates/org_contest_list.html
+++ b/mo/web/templates/org_contest_list.html
@@ -8,6 +8,8 @@ Seznam účastníků {% if site %}soutěžního místa {{ site.name }}{% else %}
 {% block breadcrumbs %}
 {{ contest_breadcrumbs(round=round, contest=contest, site=site, action="Seznam účastníků") }}
 {% endblock %}
+{% set id = contest.contest_id %}
+{% set site_id = site.place_id if site else None %}
 
 {% block body %}
 <div class="form-frame">
@@ -20,8 +22,10 @@ Seznam účastníků {% if site %}soutěžního místa {{ site.name }}{% else %}
 		{{ wtf.form_field(filter.participation_state) }}
 		<div class="btn-group">
 			{{ wtf.form_field(filter.submit, class='btn btn-primary') }}
+			{% if table %}
 			<button class="btn btn-default" name="format" value="cs_csv" title="Stáhnout celý výsledek v CSV">↓ CSV</button>
 			<button class="btn btn-default" name="format" value="tsv" title="Stáhnout celý výsledek v TSV">↓ TSV</button>
+			{% endif %}
 		</div>
 	{% if not site %}
 	</div>
@@ -32,6 +36,9 @@ Seznam účastníků {% if site %}soutěžního místa {{ site.name }}{% else %}
 </form>
 </div>
 
-{% include 'parts/org_participants_table_actions.html' %}
-
+{% if table %}
+	{% include 'parts/org_participants_table_actions.html' %}
+{% else %}
+	{% include 'parts/org_participants_emails.html' %}
+{% endif %}
 {% endblock %}
diff --git a/mo/web/templates/org_round_list.html b/mo/web/templates/org_round_list.html
index 417006a92f9cc1c543874a4bc3d150c5c0bce603..69b4ca3fd586f25b0546ad0d7c51c240aafa3138 100644
--- a/mo/web/templates/org_round_list.html
+++ b/mo/web/templates/org_round_list.html
@@ -5,6 +5,7 @@
 {% block breadcrumbs %}
 {{ contest_breadcrumbs(round=round, action="Seznam účastníků") }}
 {% endblock %}
+{% set id = round.round_id %}
 
 {% block body %}
 <div class="form-frame">
@@ -18,10 +19,12 @@
 	<div class="form-row" style="margin-top: 5px;">
 		<div class="btn-group">
 			{{ wtf.form_field(filter.submit, class='btn btn-primary') }}
+			{% if table %}
 			<button class="btn btn-default" name="format" value="cs_csv" title="Stáhnout celý výsledek v CSV">↓ CSV</button>
 			<button class="btn btn-default" name="format" value="tsv" title="Stáhnout celý výsledek v TSV">↓ TSV</button>
+			{% endif %}
 		</div>
-
+		{% if table %}
 		<div style="float: right">
 			Stránka {{ filter.offset.data // filter.limit.data + 1}} z {{ (count / filter.limit.data)|round(0, 'ceil')|int }}:
 			<div class="btn-group">
@@ -41,13 +44,20 @@
 		</div>
 		{% set max = filter.offset.data + filter.limit.data if filter.offset.data + filter.limit.data < count else count %}
 		Zobrazuji záznamy <b>{{filter.offset.data + 1}}</b> až <b>{{ max }}</b> z <b>{{count}} nalezených účastníků</b>.
+		{% else %}
+		Celkem <b>{{count|inflected('nalezený účastník', 'nalezení účastníci', 'nalezených účastníků')}}</b>.
+		{% endif %}
 	</div>
 </form>
 </div>
 
-{% include 'parts/org_participants_table_actions.html' %}
-
-<br>
-<i>Upozornění: Můžete editovat jen účastníky soutěžící v oblastech, ke kterým máte právo.</i>
-
+{% if table %}
+	{% include 'parts/org_participants_table_actions.html' %}
+	{% if form_actions %}
+	<br>
+	<i>Upozornění: Můžete editovat jen účastníky soutěžící v oblastech, ke kterým máte právo.</i>
+	{% endif %}
+{% else %}
+	{% include 'parts/org_participants_emails.html' %}
+{% endif %}
 {% endblock %}
diff --git a/mo/web/templates/parts/org_participants_emails.html b/mo/web/templates/parts/org_participants_emails.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e9ca863d29620bfabddfc223ca69f3a0d64148e
--- /dev/null
+++ b/mo/web/templates/parts/org_participants_emails.html
@@ -0,0 +1,19 @@
+<a class="btn btn-default pull-right" style="margin-top: 15px;"
+   href="{{ url_for('org_contest_list', id=id, site_id=site_id, **request.args) if contest else url_for('org_round_list', id=id, **request.args) }}">
+	Zpět na tabulku účastníků
+</a>
+
+<h3>E-mailové adresy</h3>
+<div class="form-frame">
+{% if emails %}
+<p>Pokud máte e-mailového klienta, který umí odkazy typu <code>mailto:</code>, tak vám následující tlačítko předvyplní nový email:
+<a class="btn btn-primary" href="{{ mailto_link }}">Vytvořit email pro {{ count|inflected("adresáta", "adresáty", "adresátů") }}</a>
+
+<p>Emailové adresy si také můžete zkopírovat z následujícího pole. Prosím posílejte jako <b>skrytou kopii</b>, ať účastníci nevidí navzájem své emaily.</p>
+<code><textarea id="emails-textarea" class="form-control" readonly style="resize: none;" onclick="this.focus(); this.select();">
+{{ emails|join('\n')|escape }}</textarea></code>
+{% else %}<i>Žádné emailové adresy k vypsání.</i>{% endif %}
+</div>
+<script type="text/javascript">
+document.getElementById('emails-textarea').style.height = (document.getElementById('emails-textarea').scrollHeight + 5) + "px";
+</script>
diff --git a/mo/web/templates/parts/org_participants_table_actions.html b/mo/web/templates/parts/org_participants_table_actions.html
index dc98b92903e4d0cd2978b840a025a42e22e83d39..9838f8348e226f31e1775771f141005dbe8bb811 100644
--- a/mo/web/templates/parts/org_participants_table_actions.html
+++ b/mo/web/templates/parts/org_participants_table_actions.html
@@ -1,7 +1,16 @@
 {% if action_form %}
 <form action="" method="POST" class="form form-horizontal" role="form">
+{% endif %}
+
 	{{ table.to_html() }}
 
+	<a class="btn btn-primary pull-right"
+	   title="Zobrazí emailové adresy ve snadno zkopírovatelném formátu"
+	   href="{{ url_for('org_contest_list_emails', id=id, site_id=site_id, **request.args) if contest else url_for('org_round_list_emails', id=id, **request.args) }}">
+		Vypsat emailové adresy
+	</a>
+
+{% if action_form %}
 	{{ action_form.csrf_token }}
 	<h3>Provést akci</h3>
 	<div class="form-frame">
@@ -45,7 +54,6 @@
 	</div>
 </form>
 {% else %}
-{{ table.to_html() }}
 <p>
 <i>Nemáte právo k editaci účastníků v této oblasti.</i>
 </p>