30 May 2023
Download your Revit 2d views as PDFs
Introduction
In your current workflow, you might need to generate the PDFs from your designs to communicate with other teams, go through design reviews, archiving, version control, or any other pdf-related scenario.
If you need to generate PDFs from your Revit designs, there's a way to do that easily and quickly through Model Derivative (as long as your files fulfill some conditions).
That's what we'll cover in this blog post.
Special thanks to Elton Gjata, Keith Davidge, Luc Deckinga, Mario Romero, and Zuzanna Czapla for bringing this interesting case to us and helping through the development of this sample.
The prerequisites
For this workflow to work, you'll need a few prerequisites:
- Your Revit project file needs to be from version 2022 or later to be able to generate PDF (refer here)
- Your 2d views need to be published (refer here)
- Your Revit project file needs to be published after November 4th of 2021, so we can check its version (refer here)
- Your browser needs to be configured to download PDFs instead of just opening a new tab to preview them (refer here)
- You might need to disable your browser pop-up blocker, as it opens one tab for each PDF being downloaded (refer here)
With these taken care of, you can move forward with the workflow shown here.
If that's not your case (maybe your 2d views weren't published) you can still download your PDFs using the Design Automation approach described here.
How can I download my PDFs?
With the 4 prerequisites granted, let's download your PDFs.
As explained in the blog mentioned by prerequisite 1, your models are already generating PDFs for 2d views by default, so we just need to download them using Model Derivative signedcookies endpoint. We can basically generate a URL to download each view.
In our sample, we're doing that through the snippet below:
service.getDownloadUrls = async (version_id, token) => {
const resp = await new APS.DerivativesApi().getManifest(version_id.replace('-', '/'), null, internalAuthClient, token);
let derivatives = resp.body.derivatives[0].children;
let pdfViews = derivatives.filter(v => v.role == '2d' && !!v.properties['Print Setting']);
let pdfDerivatives = pdfViews.map(v => v.children.find(d => d.role == "pdf-page"));
let downloadUrls = [];
let revitVersion = resp.body.derivatives[0].properties["Document Information"].RVTVersion;
if (!!revitVersion || parseInt(revitVersion) > 2022) {
for (const derivative of pdfDerivatives) {
let newDerivativeUrl = await getSignedUrlFromDerivative(version_id.replace('-', '_'), derivative, token);
downloadUrls.push(newDerivativeUrl);
}
}
return { "derivatives": downloadUrls, "RVTVersion": revitVersion };
};
async function getSignedUrlFromDerivative(urn, derivative, token) {
let url = `https://developer.api.autodesk.com/modelderivative/v2/designdata/${urn.replaceAll('=', '')}/manifest/${derivative.urn}/signedcookies?useCdn=true`;
let options = {
method: 'GET',
headers: {
Authorization: 'Bearer ' + token.access_token
}
};
let resp = await fetch(url, options);
let respJSON = await resp.json();
let policy = resp.headers.raw()['set-cookie'][0].split('=')[1].split(';')[0];
let keypair = resp.headers.raw()['set-cookie'][1].split('=')[1].split(';')[0];
let signature = resp.headers.raw()['set-cookie'][2].split('=')[1].split(';')[0];
let data = {
"name": derivative.urn.split('/').slice(-1)[0],
"url": respJSON.url,
"CloudFront-Policy": policy,
"CloudFront-Key-Pair-Id": keypair,
"CloudFront-Signature": signature
};
Once on the client side, we can simply download each of the signed URLs.
Feel free to check the source code and a live demo below.
Considerations to move to production
As this is a sample, we didn't cover considerations regarding performance and error handling.
In your production-ready app, you should handle 429 and enqueuing jobs, as described in improve app resilience blog.
You can also upload the PDFs to a cloud repository instead of just downloading them on your local machine.