问题
I need to merge two google docs into one. I know how to copy one doc, but I need to create a new document which contains the contents of two google docs.
I came up with the following:
const auth = await authorize(credentials)
const docs = google.docs({version: 'v1', auth})
const drive = google.drive({version: 'v3', auth})
const file1ToCopy = await docs.documents.get({documentId: FILE_1_ID})
const file2ToCopy = await docs.documents.get({documentId: file_2_ID})
const {body: body1ToCopy} = file1ToCopy.data
const {body: body2ToCopy} = file2ToCopy.data
await drive.files.create({
resource: {
name: `test ${moment().toString()}`,
mimeType: 'application/vnd.google-apps.document',
},
media: {
body: {...body1ToCopy, ...body2ToCopy}, // This is not the correct way, body accepts only stream also the bodies received from documents.get are objects, so they probably can not be combined like this...
},
})
As you can see I am able to get the individual document's bodies but I am unable to insert them into one file.
Can anyone help me with that?
回答1:
Instances of Document are not valid arguments to provide to Files: create. You should first retrieve the contents you want to add to your destination Document, and then insert these contents using Docs API.
I'd suggest you to (1) make a copy of the first of the Docs (this copy will be the merged Doc), (2) retrieve the contents from the second Doc, and (3) insert the contents retrieved in previous step to the copied Doc.
You could do something along the following lines:
Step 1. Copy the first Document:
Make a copy of the first Document with Files: copy. The contents from the second Document will be appended to this copy.
Step 2. Extract content from second Document:
In order to extract the body content from the second Doc, you have to take into account the structure of a Google Document: documents.get retrieves an instance of Document, which contains the contents you want to append to your new document, but is not the contents themselves.
The body content in a Document resource is basically made of a list of StructuralElements inside content
, like this:
{
"documentId": string,
"title": string,
"body": {
"content": [
{
object (StructuralElement)
}
]
},
// Other document props
}
You would have to iterate through each StructuralElement
in content
and store all the information needed to append the content in next step (these would include, at least, the type of structural element —since depending on this, one method or another would have to be used— and the text content). I'd suggest you to store this information to an array of objects, to be used later.
As an example, a pretty decent explanation of how to extract the text from a Document can be found here (even though the example only contains samples in Java and Python, it shouldn't be specially hard to "translate" this to Node): Extract the text from a document. You could keep information on other properties, like the element type (not just the text), but the basic idea is very similar.
Step 3. Append contents to new document:
Once you have successfully retrieved the structural elements from the second document, you would have to use Docs API to append these elements to the merged document using documents.batchUpdate.
Depending on which type of structural element you have to append every time, a different request might be needed. For example, if the structural element is a paragraph that only contains text, you can use InsertTextRequest to append the text. Or if you want to append a table, you would have to use InsertTableRequest. Because of this, the script would have to check each structural element type before appending it to the Document.
Reference:
- Drive API: Files.copy
- Structure of a Google Docs document
- Docs API: Extract the text from a document
- Docs API: documents.batchUpdate
来源:https://stackoverflow.com/questions/61302108/merge-two-google-documents-together-using-node-googleapis