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:

  1. Your Revit project file needs to be from version 2022 or later to be able to generate PDF (refer here
  2. Your 2d views need to be published (refer here)
  3. Your Revit project file needs to be published after November 4th of 2021, so we can check its version (refer here)
  4. Your browser needs to be configured to download PDFs instead of just opening a new tab to preview them (refer here)
  5. 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.

SOURCE

LIVE DEMO

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.

Related Article

Posted By

João Martins

João Martins

Joined the Developer Advocates team in 2020, João works mostly with .NET application. He is a Civil Engineer graduate with experience in software development. You can count on him to help you with your AEC related topics.

Jaime Rosales

Jaime Rosales

Jaime Rosales is a Senior Developer Advocate with Autodesk Forge. He’s part of the team that helps partners/customers create new products and transition to the cloud with the use of Autodesk’s new Platform - Forge. He joined Autodesk in 2011 through the acquisition of Horizontal Systems the company that developed the cloud-based collaboration systems—now known as BIM 360 Glue the Glue. He was responsible for...