Google Docs API - How to initialize document content when creating new document?

I’m working with the Google Docs API and can successfully read documents but I’m stuck on creating new documents with pre-filled content. My goal is to copy content from one document and use it to initialize a new document.

Here’s how I get the source document:

Document sourceDoc = docsService.documents().get(SOURCE_DOC_ID).execute();

I can extract the body content like this:

Body documentContent = sourceDoc.getBody();

But when I try to create a new document with this content, it doesn’t work:

Document newDoc = new Document()
    .setTitle("My New Document")
    .setBody(documentContent);

newDoc = docsService.documents().create(newDoc).execute();

The document gets created but without the body content I’m trying to set. Am I missing something in my approach? Is there a different way to initialize document content during creation?

Yeah, this limitation caught me off guard too. The documents().create() method completely ignores any body content you try to pass - it only creates empty documents with basic stuff like the title. I had to treat it as two separate steps. First create the empty doc, then parse through your source document’s elements and turn each one into batch requests. Text becomes InsertTextRequest objects, but you’ll need UpdateParagraphStyleRequest for paragraph styles. Tables need InsertTableRequest plus individual cell updates. Here’s something I learned the hard way: insert everything sequentially from the start instead of trying to build it all at once. The API handles formatting inheritance way better this way, and you won’t get index calculation errors with complex documents.

The Google Docs API won’t let you set body content when creating a document - I hit this same wall building a templating system last year. The create operation only takes a title and basic metadata, then ignores whatever body content you throw at it. Here’s what actually works: create the empty document first, then immediately hit it with batchUpdate to fill it in. You’ll need to break down your source document and convert each piece into separate requests. For text, use InsertTextRequest with location set to index 1. Formatting’s the pain - bold, italic, and other styling each need their own requests targeting specific text ranges. Pro tip: if you’re adding multiple elements, insert them in reverse order or the indices shift around and everything gets scrambled.

Been there, done that. Google Docs API sucks for this - you have to manually parse every element and convert it to batch requests.

I hit this same wall when creating hundreds of docs from templates. The create-then-update process gets messy fast, especially with complex formatting, tables, or images.

Automation saved me. I built a workflow that handles the whole document creation without touching the API directly. It grabs content from any source, keeps all formatting, and cranks out new docs in seconds. No more fighting with InsertTextRequest objects or element indices.

Bonus: it works with Word docs and PDFs too. Way cleaner than writing hundreds of lines just to copy content.

Check it out: https://latenode.com

yea, this trips up evryone with the Docs API. you can’t pass body content when creating a doc - it just ignores it silently, which is super annoying. I always create an empty doc first, then immediately use batchUpdate with insert requests. Just make sure you start inserting at index 1, not 0, or you’ll get errors.

The Google Docs API only allows for the creation of empty documents. To initialize a document with content, you’ll need to follow a two-step process. First, create the document using docsService.documents().create(newDoc).execute(). Once the document is created, you’ll retrieve the content from your source document. Each content element should be converted into specific insert requests, such as InsertTextRequest or InsertPageBreakRequest. This means you cannot directly use the Body object. If your source document includes tables or images, you will need to implement specific logic to handle those elements separately. Basic text can be added with InsertTextRequest, but formatting will require additional handling.

The Problem:

You’re trying to create a new Google Doc using the Google Docs API, pre-populated with content from an existing document. Your code creates the new document, but the body content is missing. You’ve successfully retrieved the body content from the source document, but setting it during the creation of the new document doesn’t work as expected.

:thinking: Understanding the “Why” (The Root Cause):

The Google Docs API’s documents().create() method doesn’t allow you to directly set the body content when creating a new document. It only accepts the title and other basic metadata. Attempting to provide body content during creation will silently ignore that data. This is a fundamental limitation of the API’s design. To achieve your goal, you need a two-step process: create the empty document, then populate it with content using subsequent API calls.

:gear: Step-by-Step Guide:

  1. Create the Empty Document: First, create a new, empty Google Document using your existing docsService.documents().create() method. This will provide a blank document with an ID that you can subsequently use to add content.

  2. Retrieve Content from Source Document: Obtain the content elements from your source document using sourceDoc.getBody().getContent(). This will give you an array of elements representing the structure and content of your source document (paragraphs, tables, images, etc.).

  3. Batch Update to Populate the New Document: This is the core of the solution. You cannot simply set the body of the new document; instead you must use the docsService.documents().batchUpdate() method. This method accepts a request body containing a list of individual requests, one for each element you want to add to the new document. Each content element from your source document needs to be converted into the appropriate request type, such as:

    • Text: Use InsertTextRequest to add text. Specify the location (index) where the text should be inserted. Remember that indices are 1-based, not 0-based.
    • Paragraph Formatting: Use UpdateParagraphStyleRequest to apply formatting (bold, italics, etc.) to specific paragraphs.
    • Tables: Use InsertTableRequest to add tables, followed by individual UpdateTableCellRequest calls to populate each cell.
    • Images: Images must be uploaded separately, obtaining a URL that can then be inserted using InsertInlineImageRequest.

    The following code snippet illustrates the basic structure for batch updating, focusing on text insertion:

    List<Request> requests = new ArrayList<>();
    // Assuming 'elements' is the array of elements from sourceDoc.getBody().getContent()
    for (int i = 0; i < elements.size(); i++){
        if (elements.get(i) instanceof Paragraph){
            Paragraph paragraph = (Paragraph) elements.get(i);
            for (Element element : paragraph.getElements()){
                if (element instanceof TextRun){
                    TextRun textRun = (TextRun) element;
                    requests.add(new Request()
                            .setInsertText(new InsertTextRequest()
                                    .setText(textRun.getContent())
                                    .setLocation(new Location().setIndex(i + 1)))); //Remember 1-based indexing
                }
            }
        }
    }
    
    BatchUpdateDocumentRequest batchUpdateRequest = new BatchUpdateDocumentRequest().setRequests(requests);
    Document updatedDoc = docsService.documents().batchUpdate(newDoc.getDocumentId(), batchUpdateRequest).execute();
    

    Note: This is a simplified example for text insertion only. You’ll need to adapt and extend this code to handle other element types (tables, images, formatting) present in your source document’s content.

  4. Handle Different Element Types: The most crucial part is correctly handling different element types within the source document’s content. You’ll need to add conditional logic to your loop to process each type correctly (paragraphs, tables, lists, images, etc.). Each element type will require a specific request type within the BatchUpdateDocumentRequest.

  5. Iterative Development and Testing: It’s highly recommended to develop and test this solution iteratively. Start by handling a simplified version of your source document (only text, for instance) and gradually add complexity, testing at each step. This will help you identify and debug potential issues related to element handling or indexing.

:mag: Common Pitfalls & What to Check Next:

  • Index Management: Carefully manage indices when inserting elements. Incorrect indexing can lead to content being placed in the wrong locations or formatting being applied incorrectly. Remember that Google Docs API uses 1-based indexing.
  • Error Handling: Implement comprehensive error handling to catch issues during the batch update process. Log errors for easier debugging.
  • Formatting: Replicating complex formatting accurately can be challenging. Test thoroughly and debug as needed.
  • Large Documents: Processing very large documents can be slow. Consider optimizing your code for performance or using pagination if necessary.

:speech_balloon: Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.