Reputation: 367
I need to copy tables's cell with text and images to another table in another file.
# -*- coding: utf-8 -*-
from docx import Document
oldDocument = Document("d:/first.docx")
newDocument = Document()
temp = oldDocument.tables[9].rows[1].cells[1]
table = newDocument .add_table(rows=1, cols=1)
table.rows[0].cells[0] = temp
newDocument .save("d:/second.docx")
This is example of table
And this this Error TypeError: 'tuple' object does not support item assignment
Upvotes: 2
Views: 1812
Reputation: 651
For anyone who visits this question while googling, this is actually doable.
First of all, anything from one document can be inserted to the other document preserving the basic styles as described in this GitHub comment. Sample code from there:
def direct_insert(doc_dest, doc_src):
for p in doc_src.paragraphs:
inserted_p = doc_dest._body._body._insert_p(p._p)
if p._p.get_or_add_pPr().numPr:
inserted_p.style = "ListNumber"
The last two lines are called a "dirty hack" for lists in the above mentioned comment. Thought it does not work pretty well. To make it work with lists one will have to dig a bit deeper. If
clause is okay, but to change the style we will refer to this comment in another thread.
Code snippet from there:
from docx import Document
from docx.shared import Inches
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
def create_list(paragraph, list_type):
p = paragraph._p #access to xml paragraph element
pPr = p.get_or_add_pPr() #access paragraph properties
numPr = OxmlElement('w:numPr') #create number properties element
numId = OxmlElement('w:numId') #create numId element - sets bullet type
numId.set(qn('w:val'), list_type) #set list type/indentation
numPr.append(numId) #add bullet type to number properties list
pPr.append(numPr) #add number properties to paragraph
ordered = "5"
unordered = "1"
document = Document()
paragraph = document.add_paragraph("Hello", "List Paragraph")
create_list(paragraph, unordered)
paragraph = document.add_paragraph("Hello Again", "List Paragraph")
create_list(paragraph, unordered)
paragraph = document.add_paragraph("Goodbye", "List Paragraph")
create_list(paragraph, unordered)
paragraph = document.add_paragraph("Hello", "List Paragraph")
create_list(paragraph, ordered)
paragraph = document.add_paragraph("Hello Again", "List Paragraph")
create_list(paragraph, ordered)
paragraph = document.add_paragraph("Goodbye", "List Paragraph")
create_list(paragraph, ordered)
document.save("bullet list demo.docx")
Credits to berezovskyi and panoptical.
Now given the information from the research above, the code from question should look like:
# -*- coding: utf-8 -*-
from docx import Document
oldDocument = Document("d:/first.docx")
newDocument = Document()
temp = oldDocument.tables[9].rows[1].cells[1]
table = newDocument.add_table(rows=1, cols=1)
for p in temp:
table.rows[0].cells[0]._element._insert_p(p._p)
newDocument.save("d:/second.docx")
As the original question does not have lists, if
clause is not included.
Upvotes: 0
Reputation: 28883
You can't simply copy an object from one document to another. python-docx
API objects are proxy objects, meaning they are a wrapper around the XML that actually constitutes the paragraph, cell, etc.
You'll need to read the content from the source document, then create the required structure (like table, cells, paragraphs) in the target document, placing the content where it should go.
You may be able to do something a little fancier if you go down to the lxml
layer, perhaps copying the text with all its formatting (superscripts etc.), but that will require digging into the internals and understanding the underlying XML structure. If you search on 'python-docx workaround function' you should find some examples to get you started.
Upvotes: 1