I hear you, but there's very little you can actually do here I.M.H.O.
You can't server side block or redirect these as the the # and ! don't get passed as part of a network request
You can't robots.txt, firstly for the reasons of it being parsed, but again, they would request the URL without the #!
So the two realistic options really are:
1. Rely on canonicals, like you're currently doing, and live with the reporting
2. You could, at a push, use client-side JavaScript redirects, but I think you'd be worse off in terms of it consuming crawl budget (it have to crawl this, render, AND then redirect), all to achieve what would in the end of the day amount to moving them from one reason they aren't indexed to a different reason in the report.