It looks like you want a few things from a single button press.

1. Initiate request
2. Process request
3. Prompt user

[WP AJAX](https://codex.wordpress.org/AJAX_in_Plugins) will let you utilize jQuery to send a request to [`admin ajax (action)`](https://www.smashingmagazine.com/2011/10/how-to-use-ajax-in-wordpress/) and trigger your process using [`shell_exec `](https://stackoverflow.com/questions/7093860/php-shell-exec-vs-exec). When complete you'll compose the response with [`wp_send_json_success()`](https://codex.wordpress.org/Function_Reference/wp_send_json_success) and read the result back on your main page. If the process has completed, you can prompt the user at that point to download the file with the information you provided in your AJAX response.

You can also utilize custom endpoints with the [REST API](http://v2.wp-api.org/extending/adding/) instead of `admin-ajax.php` which will handle encoding on the return value.

    add_action( 'rest_api_init', function () {

    	register_rest_route( 'pdf/v1', '/process/', array(
    		'methods' => 'GET',
    		'callback' => 'process_pdf',
    	) );
    } );

How you prompt the user is up to you.

If you went with [`admin_post_(action)`](https://codex.wordpress.org/Plugin_API/Action_Reference/admin_post_(action)) you could do must of the above and [automatically](https://wordpress.stackexchange.com/questions/3480/how-can-i-force-a-file-download-in-the-wordpress-backend) initiate the download with a header response from PHP.