Index: src/wp-admin/includes/file.php
===================================================================
--- src/wp-admin/includes/file.php	(revision 43044)
+++ src/wp-admin/includes/file.php	(working copy)
@@ -2040,6 +2040,7 @@
 		fclose( $file );
 	}
 
+	// Create the temporary HTML report.
 	$stripped_email       = str_replace( '@', '-at-', $email_address );
 	$stripped_email       = sanitize_title( $stripped_email ); // slugify the email address
 	$obscura              = md5( rand() );
@@ -2125,10 +2126,27 @@
 	fclose( $file );
 
 	// Now, generate the ZIP.
-	$archive_filename = $file_basename . '.zip';
-	$archive_pathname = $exports_dir . $archive_filename;
-	$archive_url      = $exports_url . $archive_filename;
+	// If we already have a path for the archive from a previous export for
+	// this request, delete the old archive and use that filename again to create
+	// the new one.
+	$archive_url      = get_post_meta( $request_id, '_export_file_url', true );
+	$archive_pathname = get_post_meta( $request_id, '_export_file_path', true );
 
+	if ( empty( $archive_pathname ) || empty( $archive_url ) ) {
+		$archive_filename = $file_basename . '.zip';
+		$archive_pathname = $exports_dir . $archive_filename;
+		$archive_url      = $exports_url . $archive_filename;
+
+		// Save the url and path in the request.
+		update_post_meta( $request_id, '_export_file_url', $archive_url );
+		update_post_meta( $request_id, '_export_file_path', $archive_pathname );
+	}
+
+	// If the archive already exists, unlink it so we can build it afresh
+	if ( ! empty( $archive_pathname ) && file_exists( $archive_pathname ) ) {
+		@unlink( $archive_pathname );
+	}
+
 	$zip = new ZipArchive;
 
 	if ( TRUE === $zip->open( $archive_pathname, ZipArchive::CREATE ) ) {
@@ -2138,12 +2156,8 @@
 		wp_send_json_error( __( 'Unable to open export file (archive) for writing' ) );
 	}
 
-	// And remove the HTML file.
+	// And remove the temporary HTML file.
 	unlink( $html_report_pathname );
-
-	// Save the export file in the request.
-	update_post_meta( $request_id, '_export_file_url', $archive_url );
-	update_post_meta( $request_id, '_export_file_path', $archive_pathname );
 }
 
 /**
@@ -2311,14 +2325,6 @@
 	delete_post_meta( $request_id, '_export_data_raw' );
 	update_post_meta( $request_id, '_export_data_grouped', $groups );
 
-	// And now, generate the export file, cleaning up any previous file
-	$export_path = get_post_meta( $request_id, '_export_file_path', true );
-	if ( ! empty( $export_path ) ) {
-		delete_post_meta( $request_id, '_export_file_path' );
-		@unlink( $export_path );
-	}
-	delete_post_meta( $request_id, '_export_file_url' );
-
 	// Generate the export file from the collected, grouped personal data.
 	do_action( 'wp_privacy_personal_data_export_file', $request_id );
 
