Why saveAndClose comes first
The Document service and the Drive service are two separate layers. When your script calls DocumentApp methods — appending a paragraph, filling a table cell, whatever — those changes sit in an in-memory representation that the Document service manages. DriveApp.getFileById().getAs() reads the stored file on Drive, not that in-memory state.
If you call getAs() before saveAndClose(), the PDF reflects whatever was on disk when the script started. Any edits your script made are silently absent. The first time I hit this, the PDF looked correct in the editor but arrived blank of the values the script had just written — twenty minutes of confused staring before I found the flush requirement in the API docs.
saveAndClose() does two things: it flushes the Document service buffer to disk, and it closes the service handle so the document is no longer locked by DocumentApp. After that call, DriveApp reads a file that actually contains your changes.