2013-05-31 34 views
10

. Docx modülünü denedim ve işe yaramayacaktım. Sonunda, zip dosyası modülünü kullanarak ve docx arşivindeki document.xml dosyasını değiştirerek aşağıda açıklanan yöntemi kullandım. Bunun çalışması için, belgede mevcut veya gelecekteki herhangi bir metinle eşleşmeyecek benzersiz dizeler olarak değiştirmek istediğiniz metin içeren bir şablon belgesine (docx) ihtiyacınız vardır (örn. "XXXMEETDATEXXX üzerindeki XXXCLIENTNAMEXXX ile toplantı çok iyi geçti. ").bulun ve .docx dosyası metni değiştirmek - ı bulup biraz şans ile bir docx dosyası metni değiştirmek için bir yöntem için birçok arama da yapıyorum Python

import zipfile 

replaceText = {"XXXCLIENTNAMEXXX" : "Joe Bob", "XXXMEETDATEXXX" : "May 31, 2013"} 
templateDocx = zipfile.ZipFile("C:/Template.docx") 
newDocx = zipfile.ZipFile("C:/NewDocument.docx", "a") 

with open(templateDocx.extract("word/document.xml", "C:/")) as tempXmlFile: 
    tempXmlStr = tempXmlFile.read() 

for key in replaceText.keys(): 
    tempXmlStr = tempXmlStr.replace(str(key), str(replaceText.get(key))) 

with open("C:/temp.xml", "w+") as tempXmlFile: 
    tempXmlFile.write(tempXmlStr) 

for file in templateDocx.filelist: 
    if not file.filename == "word/document.xml": 
     newDocx.writestr(file.filename, templateDocx.read(file)) 

newDocx.write("C:/temp.xml", "word/document.xml") 

templateDocx.close() 
newDocx.close() 

Sorum şu: Bu yöntemde sorun nedir? Bu şeylere oldukça yeniyim, bu yüzden başka birinin bunu anlaması gerektiğini hissediyorum. Bu, bu yaklaşımda çok yanlış bir şey olduğuna inanıyorum. Ama işe yarıyor! Burada neyi özlüyorum?

. İşte

herkes için benim düşünce sürecinin bir örneklerde başka bu şeyleri öğrenmeye çalışıyor ise:

Adım 1) anahtarlar ve öğeleri gibi yeni metin olarak değiştirmek istediğiniz metin dizeleri bir Python sözlüğü hazırlayın (örn . {"XXXCLIENTNAMEXXX": "Joe Bob", "XXXMEETDATEXXX": "31 Mayıs 2013").

Adım 2) Şablon docx dosyasını zipfile modülünü kullanarak açın.

Adım 3) ekleme erişim modu ile yeni yeni docx dosyasını açın.

Adım 4) şablonu docx dosyasından document.xml (tüm metin can) Özü ve bir metin dizesi değişkene xml okuyun.

Adım 5) Yeni metinle xml metin dizesindeki Sözlüğünüzde tanımlanan metnin tamamını değiştirmek için for döngüsü kullanın.

Adım 6) xml metin dizesini yeni bir geçici xml dosyasına yazın.

Adım 7) döngü ve kelime/document.xml dosyası HARİÇ yeni docx arşive şablon docx arşivinde tüm dosyaları kopyalamak için zipfile modül için bir kullanın.

Adım 8) Yeni bir kelime/document.xml dosyası olarak yeni docx arşive yerini metinle geçici xml dosyası yaz.

Adım 9) Şablonunuzu ve yeni docx arşivlerini kapatın.

10. Adım) Yeni docx belgenizi açın ve değiştirilen metninizin tadını çıkarın!

--Edit-- Bazen kapanış hatlarında 7 parantez ')' ve

+0

Gönderdiğiniz kodun çalıştığı ve "Neden bir başkası bunu neden yapmamış?" Diye soruyorsun. Bu neden sorun olur ki? Kodunuzdaki şahane bir bakıştan, yapılacak en doğru şey gibi görünüyor. –

+0

Tabii ki insanlar bunu daha önce yapmışlardır. Bu bir form mektubunun bir barebone uygulamasıdır. Microsoft Word (ve OpenOffice ve vb), bunu yerel olarak yapacak bir "Adres Mektup Birleştirme" işlevine sahiptir. –

+0

Bu soru konu dışı görünmektedir, çünkü çalışma kodunun gözden geçirilmesi ile ilgilidir. Codereview.SE'ye geçişi önerin –

cevap

1

11 Eksik Word garip şeyler yapar. Sen afer, genellikle kelimenin/docx için document.xml (a xml dosyasında kaydedilir orta

Kişisel belgede metnini düzenlemeden metni kaldırmak ve bir inme, örneğin içinde yeniden yazmak için çalışmalısınız Ayıklama). Bazen metninizin tek vuruşta olmaması mümkündür: Belgedeki bir yerde XXXCLIENT ve başka bir yerde NAMEXXX.Böyle

şey:

<w:t> XXXCLIENT </w:t> ... <w:t> NAMEXXX </w:t>

Bu oldukça sık nedeni dil desteği olur: o bir kelime belirli bir dilin olduğunu düşünür ve kelimeler arasındaki yapabilirsiniz zaman kelime kelime böler, o vasiyeti kelimeleri birden fazla etikete ayırın.

Çözümünüzle ilgili bir sorun, her şeyi tek bir konturla yazmak zorunda olmanızdır; bu, en kullanıcı dostu değildir.

Ben etiketleri gibi bıyık kullanan bir JS Kütüphanesi oluşturduk: {CLIENTNAME} https://github.com/edi9999/docxgenjs

Bu global algoritma ile aynı şekilde çalışan ancak yazarken içeriği (bir inme değilse çarpışma olmaz { Word'de CLIENTNAME}, metin genellikle parçalı olacak: {, CLIENTNAME,} belgede

-1

bir çözümü de kullan Word'ün arama/tek seferde metni almak için değiştirmek Örneğin

... "XXXCLIENTNAMEXXX" için arama yapın ve "XXXCLIENTNAMEXXX" ile değiştirin.