How can I use Google Apps Script to translate entire Google Docs while preserving formatting, tables, and images?

I want to create a Google Apps Script that works like the built-in “Translate Document” feature in Google Docs. The goal is to automatically translate multiple documents at once.

The problem I’m facing is that when I use LanguageApp.translate(), it only gives me plain text back. All the formatting gets lost, including table borders and other styling elements.

Here’s what I’ve tried so far:

function translateDocuments() {
  // Target folder containing documents to translate
  var sourceFolderID = '1ABCDefGhiJklMnOpQrStUvWxYz123456';
  var sourceFolder = DriveApp.getFolderById(sourceFolderID);
  var documentFiles = sourceFolder.getFiles();
  
  // Process each document in the folder
  while (documentFiles.hasNext()) {
    var currentFile = documentFiles.next();
    var currentFileID = currentFile.getId();
    
    // Convert Word docs to Google Docs format
    var wordFile = DriveApp.getFileById(currentFileID);
    var newGoogleDoc = Drive.newFile();
    var fileBlob = wordFile.getBlob();
    var convertedFile = Drive.Files.insert(newGoogleDoc, fileBlob, {convert: true});
    DocumentApp.openById(convertedFile.id).setName(wordFile.getName().slice(0, -5));
    
    // Open the converted document
    var originalDoc = DocumentApp.openById(convertedFile.id);
    
    // Create translated version with new name
    var translatedDoc = DocumentApp.create("[ENGLISH] " + wordFile.getName().slice(0, -5));
    
    // Extract and translate content
    var originalContent = originalDoc.getBody().getText();
    var translatedContent = LanguageApp.translate(originalContent, 'vi', 'en');
    translatedDoc.getBody().appendParagraph(translatedContent);
  }
}

Is there a way to translate the document while keeping all the original formatting intact?

Your problem is you’re treating the whole document like one giant text block. I hit this same wall when automating translations for client reports. Here’s what actually works: iterate through the document structure recursively. Pull text from individual pieces - paragraphs, table cells, list items - translate each piece separately, then rebuild everything in your target document. For tables, use getNumRows() and getNumColumns() to recreate the structure. Translate cell by cell but keep the formatting like background colors and borders intact. The annoying part is nested elements - you’ll get formatted text inside table cells that needs special handling. Yeah, performance suffers because you’re making tons of translation calls, but it’s the only reliable way I’ve found that doesn’t break your document structure.

no direct way to keep formatting with LanguageApp.translate() - you’ll have to loop through each document element and rebuild everything manually. try the built-in translate feature instead using URL manipulation: https://translate.google.com/translate?sl=vi&tl=en&u= + your doc URL. might work better for batch jobs.

You need to process elements one by one instead of translating everything at once. Go through each paragraph, table cell, and text run separately while keeping their formatting intact. Here’s the trick: use getType() to figure out what kind of element you’re dealing with, then run LanguageApp.translate() on just the text while copying over stuff like fonts, colors, and alignment to your translated version. For tables, you’ll have to rebuild the whole structure in your target doc and translate each cell individually. It’s way slower than bulk translation but keeps all your formatting. I’ve done this with technical docs that had crazy layouts - works great, just plan for longer processing times if you’re dealing with lots of documents.