can't open word document after string replacements

A

Antoine De Groote

Hi there,

I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members). I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

Oh, and is this approach pythonic anyway? (I have a strong Java background.)

Regards,
antoine


import os

members = somelist

os.chdir(somefolder)

doc = file('ttt.doc', 'rb')
docout = file('ttt1.doc', 'wb')

counter = 0

for line in doc:
while line.find('ABCDEF') > -1:
try:
line = line.replace('ABCDEF', members[counter], 1)
docout.write(line)
counter += 1
except:
docout.write(line.replace('ABCDEF', '', 1))
else:
docout.write(line)

doc.close()
docout.close()
 
D

Daniel Dittmar

Antoine said:
I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members). I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

The Word document format probably contains some length information about
paragraphs etc. If you change a string to another one of a different
length, this length information will no longer match the data and the
document structure will be hosed.

Possible solutions:
1. Use OLE automation (in the python win32 package) to open the file in
Word and use Word search and replace. Your script could then directly
print the document, which you probably have to do anyway.

2. Export the template document to RTF. This is a text format and can be
more easily manipulated with Python.
for line in doc:

I don't think that what you get here is actually a line of you document.
Due to the binary nature of the format, it is an arbitrary chunk.

Daniel
 
B

Bruno Desthuilliers

Antoine said:
Hi there,

I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members).

Do you know that MS Word already provides this kind of features ?
I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

Hand-editing a non-documented binary format may lead to undesirable
results...
Oh, and is this approach pythonic anyway?

The pythonic approach is usually to start looking for existing
solutions... In this case, using Word's builtin features and Python/COM
integration would be a better choice IMHO.
(I have a strong Java
background.)

Nobody's perfect !-)
Regards,
antoine


import os

members = somelist

os.chdir(somefolder)

doc = file('ttt.doc', 'rb')
docout = file('ttt1.doc', 'wb')

counter = 0

for line in doc:

Since you opened the file as binary, you should use file.read() instead.
Ever wondered what your 'lines' look like ?-)
while line.find('ABCDEF') > -1:

..doc is a binary format. You may find such a byte sequence in it's
content in places that are *not* text content.
try:
line = line.replace('ABCDEF', members[counter], 1)
docout.write(line)

You're writing back the whole chunk on each iteration. No surprise the
resulting document is corrupted.
counter += 1

seq = list("abcd")
for indice, item in enumerate(seq):
print "%02d : %s" % (indice, item)
 
J

Jon Clements

Antoine said:
Hi there,

I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members). I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

Oh, and is this approach pythonic anyway? (I have a strong Java background.)

Regards,
antoine


import os

members = somelist

os.chdir(somefolder)

doc = file('ttt.doc', 'rb')
docout = file('ttt1.doc', 'wb')

counter = 0

for line in doc:
while line.find('ABCDEF') > -1:
try:
line = line.replace('ABCDEF', members[counter], 1)
docout.write(line)
counter += 1
except:
docout.write(line.replace('ABCDEF', '', 1))
else:
docout.write(line)

doc.close()
docout.close()

Errr.... I wouldn't even attempt to do this; how do you know each
'line' isn't going to be split arbitarily, and that 'ABCDEF' doesn't
happen to be part of an image. As you've noted, this is binary data so
you can't assume anything about it. Doing it this way is a Bad Idea
(tm).

If you want to do something like this, why not use templated HTML, or
possibly templated PDFs? Or heaven forbid, Word's mail-merge facility?


(I think MS Office documents are effectively self-contained file
systems, so there is probably some module out there which can
read/write them).

Jon.
 
A

Antoine De Groote

Thank you all for your comments.

I ended up saving the word document in XML and then using (a slightly
modified version of) my script of the OP. For those interested, there
was also a problem with encodings.

Regards,
antoine
 
A

Antoine De Groote

Bruno said:
Do you know that MS Word already provides this kind of features ?


No, I don't. Sounds interesting... What is this feature called?
I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

Hand-editing a non-documented binary format may lead to undesirable
results...
Oh, and is this approach pythonic anyway?

The pythonic approach is usually to start looking for existing
solutions... In this case, using Word's builtin features and Python/COM
integration would be a better choice IMHO.
(I have a strong Java
background.)

Nobody's perfect !-)
Regards,
antoine


import os

members = somelist

os.chdir(somefolder)

doc = file('ttt.doc', 'rb')
docout = file('ttt1.doc', 'wb')

counter = 0

for line in doc:

Since you opened the file as binary, you should use file.read() instead.
Ever wondered what your 'lines' look like ?-)
while line.find('ABCDEF') > -1:

.doc is a binary format. You may find such a byte sequence in it's
content in places that are *not* text content.
try:
line = line.replace('ABCDEF', members[counter], 1)
docout.write(line)

You're writing back the whole chunk on each iteration. No surprise the
resulting document is corrupted.
counter += 1

seq = list("abcd")
for indice, item in enumerate(seq):
print "%02d : %s" % (indice, item)

except:
docout.write(line.replace('ABCDEF', '', 1))
else:
docout.write(line)

doc.close()
docout.close()
 
B

Bruno Desthuilliers

Antoine said:
No, I don't. Sounds interesting... What is this feature called?

I don't know how it's named in english, but in french it's (well - it
was last time I used MS Word, which is quite some times ago???) "fusion
de documents".
 
R

Richie Hindle

[Antoine]
I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members).
[Bruno]
I don't know how it's named in english, but in french it's (well - it
was last time I used MS Word, which is quite some times ago???) "fusion
de documents".

"Mail Merge"?
 
S

Steve Holden

Antoine said:
No, I don't. Sounds interesting... What is this feature called?
Mail-merge, I believe.

However, if your document can be adequately represented in RTF
(rich-text format) then you could consider doing string replacements on
that. I invoice the PyCon sponsors using this rather inelegant technique.

regards
Steve
 
F

Frederic Rentsch

Antoine said:
Hi there,

I have a word document containing pictures and text. This documents
holds several 'ABCDEF' strings which serve as a placeholder for names.
Now I want to replace these occurences with names in a list (members). I
open both input and output file in binary mode and do the
transformation. However, I can't open the resulting file, Word just
telling that there was an error. Does anybody what I am doing wrong?

Oh, and is this approach pythonic anyway? (I have a strong Java background.)

Regards,
antoine


import os

members = somelist

os.chdir(somefolder)

doc = file('ttt.doc', 'rb')
docout = file('ttt1.doc', 'wb')

counter = 0

for line in doc:
while line.find('ABCDEF') > -1:
try:
line = line.replace('ABCDEF', members[counter], 1)
docout.write(line)
counter += 1
except:
docout.write(line.replace('ABCDEF', '', 1))
else:
docout.write(line)

doc.close()
docout.close()
DOC files contain housekeeping info which becomes inconsistent if you
change text. Possibly you can exchange stuff of equal length but that
wouldn't serve your purpose. RTF files let you do substitutions and they
save a lot of space too. But I kind of doubt whether RTF files can
contain pictures.

Frederic
 
D

Duncan Booth

Frederic Rentsch said:
DOC files contain housekeeping info which becomes inconsistent if you
change text. Possibly you can exchange stuff of equal length but that
wouldn't serve your purpose. RTF files let you do substitutions and they
save a lot of space too. But I kind of doubt whether RTF files can
contain pictures.

They wouldn't be a lot of use as a document file format if they couldn't
contain pictures. RTF files can contain just about anything, they can even
embed other non-rtf objects. Whether rtf applications apart from Word can
actually handle all of the tags is, of course, another question.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top