diff --git a/src/wp-admin/includes/privacy-tools.php b/src/wp-admin/includes/privacy-tools.php
index efe46cce32..9eb095b844 100644
--- a/src/wp-admin/includes/privacy-tools.php
+++ b/src/wp-admin/includes/privacy-tools.php
@@ -234,7 +234,7 @@ function _wp_personal_data_cleanup_requests() {
  * @return string The HTML for this group and its items.
  */
 function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
-	$group_html  = '<h2>';
+	$group_html  = '<h2 id="' . sanitize_title( $group_data['group_label'] ) . '">';
 	$group_html .= esc_html( $group_data['group_label'] );
 
 	$items_count = count( (array) $group_data['items'] );
@@ -271,6 +271,10 @@ function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
 		$group_html .= '</table>';
 	}
 
+	$group_html .= '<div class="return_to_top">';
+	$group_html .= '<a href="#top">' . esc_html__( '&uarr; Return to top' ) . '</a>';
+	$group_html .= '</div>';
+
 	$group_html .= '</div>';
 
 	return $group_html;
@@ -350,6 +354,7 @@ function wp_privacy_generate_personal_data_export_file( $request_id ) {
 	fwrite( $file, 'th { padding: 5px; text-align: left; width: 20%; }' );
 	fwrite( $file, 'td { padding: 5px; }' );
 	fwrite( $file, 'tr:nth-child(odd) { background-color: #fafafa; }' );
+	fwrite( $file, '.return_to_top { text-align:right; }' );
 	fwrite( $file, '</style>' );
 	fwrite( $file, '<title>' );
 	fwrite( $file, esc_html( $title ) );
@@ -360,7 +365,7 @@ function wp_privacy_generate_personal_data_export_file( $request_id ) {
 	fwrite( $file, "<body>\n" );
 
 	// Heading.
-	fwrite( $file, '<h1>' . esc_html__( 'Personal Data Export' ) . '</h1>' );
+	fwrite( $file, '<h1 id="top">' . esc_html__( 'Personal Data Export' ) . '</h1>' );
 
 	// And now, all the Groups.
 	$groups = get_post_meta( $request_id, '_export_data_grouped', true );
@@ -396,6 +401,24 @@ function wp_privacy_generate_personal_data_export_file( $request_id ) {
 	// Merge in the special about group.
 	$groups = array_merge( array( 'about' => $about_group ), $groups );
 
+	// Create TOC.
+	if ( count( $groups ) > 1 ) {
+		fwrite( $file, '<div id="table_of_contents">' );
+
+		fwrite( $file, '<h2>Table of Contents</h2>' );
+
+		fwrite( $file, '<ul>' );
+
+		foreach ( (array) $groups as $group_id => $group_data ) {
+			fwrite( $file, '<li>' );
+			fwrite( $file, '<a href="#' . sanitize_title( $group_data['group_label'] ) . '">' . $group_data['group_label'] . '</a>' );
+			fwrite( $file, '</li>' );
+		}
+
+		fwrite( $file, '</ul>' );
+		fwrite( $file, '</div>' );
+	}
+
 	// Now, iterate over every group in $groups and have the formatter render it in HTML.
 	foreach ( (array) $groups as $group_id => $group_data ) {
 		fwrite( $file, wp_privacy_generate_personal_data_export_group_html( $group_data ) );
