how can I create a function inside my plugin class that generates a
naked page? With no header, includes and all the WP html stuff?
There are many ways to do that, e.g. by using the admin_post hook just as you could see in @fuxia’s answer here (which does work in WordPress 5.8.1 for what you’re trying to do), or the parse_request hook as you could see in my answer here (for outputting an image data) — the WordPress REST API also uses the same hook.
But you said:
I’m developing a plugin and I want to add a menu entry that forces a
file download (a CSV).
So if it has to be using a standard admin page URL like http://example.com/wp-admin/admin.php?page=myplugin-data-export, then you could hook your exportCSVdata() function on the load-<page hook> hook, where in your case, the <page hook> value would be the hook name as returned by add_submenu_page():
$hook = add_submenu_page('<parent slug>, '', '<menu title>', $capability, $menu_slug, $function);
add_action( "load-$hook", [ $this, 'exportCSVdata' ] );
Then clicking the menu item would force the file download and the (CSV) file would also have a valid data (and no admin menu HTML displayed on the page).
But then, you could actually link the menu to http://example.com/wp-admin/admin-post.php?action=print.csv by passing an empty string ('') as the 6th parameter for add_submenu_page(), and set the menu slug to admin-post.php?action=print.csv:
add_submenu_page('<parent slug>, '', '<menu title>', $capability, 'admin-post.php?action=print.csv', '');
That way, I bet the admin_post hook would work as expected.
So for example, in your class constructor, you would add add_action( 'admin_post_print.csv', [ $this, 'exportCSVdata' ] );.