2013-08-21 4 views
18

में मर्ज करें मेरे पास लगभग 10 शब्द दस्तावेज़ हैं जो मैं खुले एक्सएमएल और अन्य सामान का उपयोग करके उत्पन्न करता हूं। अब मैं एक और शब्द दस्तावेज़ बनाना चाहता हूं और एक-एक करके मैं इन नव निर्मित दस्तावेज़ में शामिल होना चाहता हूं। मैं खुले एक्सएमएल का उपयोग करना चाहता हूं, किसी भी संकेत की सराहना की जाएगी।एकाधिक शब्द दस्तावेज़ों को एक ओपन एक्सएमएल

private void CreateSampleWordDocument() 
    { 
     //string sourceFile = Path.Combine("D:\\GeneralLetter.dot"); 
     //string destinationFile = Path.Combine("D:\\New.doc"); 
     string sourceFile = Path.Combine("D:\\GeneralWelcomeLetter.docx"); 
     string destinationFile = Path.Combine("D:\\New.docx"); 
     try 
     { 
      // Create a copy of the template file and open the copy 
      //File.Copy(sourceFile, destinationFile, true); 
      using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true)) 
      { 
       // Change the document type to Document 
       document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document); 
       //Get the Main Part of the document 
       MainDocumentPart mainPart = document.MainDocumentPart; 
       mainPart.Document.Save(); 
      } 
     } 
     catch 
     { 
     } 
    } 

अद्यतन (AltChunks उपयोग करते हुए): नीचे मेरी कोड है

using (WordprocessingDocument myDoc = WordprocessingDocument.Open("D:\\Test.docx", true)) 
     { 
      string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 2) ; 
      MainDocumentPart mainPart = myDoc.MainDocumentPart; 
      AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
       AlternativeFormatImportPartType.WordprocessingML, altChunkId); 
      using (FileStream fileStream = File.Open("D:\\Test1.docx", FileMode.Open)) 
       chunk.FeedData(fileStream); 
      AltChunk altChunk = new AltChunk(); 
      altChunk.Id = altChunkId; 
      mainPart.Document 
       .Body 
       .InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last()); 
      mainPart.Document.Save(); 
     } 

क्यों इस कोड को अधिलेखित कर देता है पिछले फ़ाइल जब मैं एक से अधिक फ़ाइलों का उपयोग की सामग्री? अद्यतन 2:

using (WordprocessingDocument myDoc = WordprocessingDocument.Open("D:\\Test.docx", true)) 
     { 

      MainDocumentPart mainPart = myDoc.MainDocumentPart; 
      string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 3); 
      AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId); 
      using (FileStream fileStream = File.Open("d:\\Test1.docx", FileMode.Open)) 
      { 
       chunk.FeedData(fileStream); 
       AltChunk altChunk = new AltChunk(); 
       altChunk.Id = altChunkId; 
       mainPart.Document 
        .Body 
        .InsertAfter(altChunk, mainPart.Document.Body 
        .Elements<Paragraph>().Last()); 
       mainPart.Document.Save(); 
      } 
      using (FileStream fileStream = File.Open("d:\\Test2.docx", FileMode.Open)) 
      { 
       chunk.FeedData(fileStream); 
       AltChunk altChunk = new AltChunk(); 
       altChunk.Id = altChunkId; 
       mainPart.Document 
        .Body 
        .InsertAfter(altChunk, mainPart.Document.Body 
        .Elements<Paragraph>().Last()); 
      } 
      using (FileStream fileStream = File.Open("d:\\Test3.docx", FileMode.Open)) 
      { 
       chunk.FeedData(fileStream); 
       AltChunk altChunk = new AltChunk(); 
       altChunk.Id = altChunkId; 
       mainPart.Document 
        .Body 
        .InsertAfter(altChunk, mainPart.Document.Body 
        .Elements<Paragraph>().Last()); 
      } 
     } 

इस कोड Test2 डेटा दो बार Test1 डेटा के स्थान पर साथ ही जोड़कर है। मतलब मैं:

Test 
Test2 
Test2 

के बजाय:

Test 
Test1 
Test2 
+2

chirs जैसा बताया इसके बजाय, आप एक इस तरह एसडीके द्वारा उत्पन्न हो , आप सभी AltChunk के लिए एक ही आईडी का उपयोग कर रहे हैं। वे अद्वितीय होना चाहिए। – Flowerking

+1

ठीक है, अब यह किया गया है, मेरे साथ धैर्य बनाए रखने के लिए धन्यवाद। –

+1

मुझे यह देखने में खुशी है कि आपने अंततः अपनी समस्या हल की है :) हाँ, यह Altchunkid से संबंधित था। मैंने अपना जवाब संपादित कर दिया है क्योंकि यह शायद बहुत स्पष्ट नहीं था। – Chris

उत्तर

17

केवल ओपनएक्सएमएल एसडीके का उपयोग करके, आप एकाधिक दस्तावेज़ को एक में मर्ज करने के लिए AltChunk तत्व का उपयोग कर सकते हैं।

यह लिंक the-easy-way-to-assemble-multiple-word-documents और यह एक How to Use altChunk for Document Assembly कुछ नमूने प्रदान करता है।

संपादित करें 1

अपने कोड अद्यतन सवाल (अद्यतन # 1) में altchunk का उपयोग करता है के आधार पर, यहाँ वीबी है।नेट कोड मैं परीक्षण किया है और जिनके मेरे लिए एक आकर्षण की तरह काम करता है:

Using myDoc = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open("D:\\Test.docx", True) 
     Dim altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 2) 
     Dim mainPart = myDoc.MainDocumentPart 
     Dim chunk = mainPart.AddAlternativeFormatImportPart(
      DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML, altChunkId) 
     Using fileStream As IO.FileStream = IO.File.Open("D:\\Test1.docx", IO.FileMode.Open) 
      chunk.FeedData(fileStream) 
     End Using 
     Dim altChunk = New DocumentFormat.OpenXml.Wordprocessing.AltChunk() 
     altChunk.Id = altChunkId 
     mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements(Of DocumentFormat.OpenXml.Wordprocessing.Paragraph).Last()) 
     mainPart.Document.Save() 
End Using 

संपादित 2

दूसरे अंक (अद्यतन 2 #)

इस कोड को जोड़कर किया जाता है टेस्ट 1 डेटा को के रूप में टेस्ट 1 डेटा के स्थान पर दो बार टेस्ट 2 डेटा।

altchunkid से संबंधित है।

प्रत्येक दस्तावेज़ आप मुख्य दस्तावेज़ में मर्ज करना चाहते हैं के लिए, आप की जरूरत है:

  1. एक Idजो अद्वितीय होना चाहिए साथ mainDocumentPart में एक AlternativeFormatImportPart जोड़ें। इस तत्व में सम्मिलित डेटा
  2. शरीर में Altchunk तत्व जोड़ें जिसमें आपने id को पिछले AlternativeFormatImportPart पर संदर्भित करने के लिए सेट किया है।

अपने कोड में, आप सभी AltChunks के लिए एक ही आईडी का उपयोग कर रहे हैं। यही कारण है कि आप एक ही पाठ को कई बार देखते हैं।

मुझे यकीन है कि altchunkid अपने कोड के साथ अनूठा होगा नहीं कर रहा हूँ: string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 2);

आप एक विशिष्ट मूल्य निर्धारित करने की आवश्यकता नहीं है, तो मेरा सुझाव है कि आप स्पष्ट रूप AltChunkId जब आप AlternativeFormatImportPart जोड़ने सेट नहीं करने के लिए।

VB.Net

Dim chunk As AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML) 
Dim altchunkid As String = mainPart.GetIdOfPart(chunk) 

सी #

सी # में उपयोग करने के लिए
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML); 
string altchunkid = mainPart.GetIdOfPart(chunk); 
+0

यह वह नहीं कर रहा है जो मैं करना चाहता हूं, इसमें कोई अपवाद नहीं है। मैं Altchunks के साथ अपना अद्यतन कोड पोस्ट कर रहा हूँ। –

+0

क्या मुझे डॉकएक्स फ़ाइल में कुछ करने की ज़रूरत है, जैसे बुकमार्क प्रकार अन्य क्रिया जोड़ना? –

+1

@ItiTyagi नहीं, मेरे परीक्षण में, मैंने अभी एक साधारण पाठ (टेक्स्ट 1 और टेक्स्ट 2) के साथ दो फाइलें बनाई हैं। और इस कोड को चलाने के बाद, जब मैं इसे खोलता हूं तो फ़ाइल Test.docx में दो पैराग्राफ होते हैं। – Chris

7

वहाँ एक अच्छा आवरण एपीआई (दस्तावेज़ बिल्डर 2.2) खुला एक्सएमएल विशेष रूप से विलय करने के लिए पैराग्राफ को चुनने के लचीलेपन के साथ दस्तावेजों विलय करने के लिए, डिज़ाइन किया गया है चारों ओर आदि। आप इसे here से डाउनलोड कर सकते हैं।

प्रलेखन और स्क्रीन इसका उपयोग कैसे करती है इस पर here है।

अद्यतन: कोड नमूना

var sources = new List<Source>(); 
//Document Streams (File Streams) of the documents to be merged. 
foreach (var stream in documentstreams) 
{ 
     var tempms = new MemoryStream(); 
     stream.CopyTo(tempms); 
     sources.Add(new Source(new WmlDocument(stream.Length.ToString(), tempms), true)); 
} 

    var mergedDoc = DocumentBuilder.BuildDocument(sources); 
    mergedDoc.SaveAs(@"C:\TargetFilePath"); 

प्रकार Source और WmlDocument दस्तावेज़ बिल्डर एपीआई से कर रहे हैं।

तुम भी रूप में करने के लिए सीधे यदि आप चाहें तो फ़ाइल पथ जोड़ सकते हैं:

sources.Add(new Source(new WmlDocument(@"C:\FileToBeMerged1.docx")); 
sources.Add(new Source(new WmlDocument(@"C:\FileToBeMerged2.docx")); 

AltChunk और Document Builder दृष्टिकोणों के बीच मिले इस Nice Comparison दस्तावेजों विलय करने के लिए - लोगों की आवश्यकताओं के आधार को चुनना सहायक।

आप दस्तावेज़ों को मर्ज करने के लिए DocX लाइब्रेरी का भी उपयोग कर सकते हैं, लेकिन मैं दस्तावेजों को विलय करने के लिए दस्तावेज़ निर्माता को पसंद करता हूं।

उम्मीद है कि इससे मदद मिलती है।

+0

क्या कोडिंग के माध्यम से खुले एक्सएमएल में कोई तरीका है क्योंकि यह कार्य वास्तव में मुझे खा रहा है, और मैं किसी भी अन्य उपकरण आदि का उपयोग नहीं कर सकता। –

+1

ये पुस्तकालय ओपनएक्सएमएल के आसपास ओपनसोर्स रैपर हैं। दस्तावेज़ बिल्डर विलय करने के लिए ओपन एक्सएमएल एसडीके का उपयोग कर रहा है और कोई कठोर निर्भरता नहीं है। दस्तावेजों को विलय करना एक साधारण काम नहीं है, साथ ही सामग्री को छोड़कर आपको शैलियों को माइग्रेट करना होगा + अन्य खुले एक्सएमएल भागों को रिश्तों को खोए बिना! और जब आपके पास दस्तावेज़ में चित्र होते हैं तो यह एक दुःस्वप्न बन जाता है। दस्तावेज़ बिल्डर एपीआई का स्रोत कोड आपको इसका एक विचार देगा। – Flowerking

+0

मुझे केवल एक पृष्ठ के रूप में सामग्री जोड़ने की आवश्यकता है, ताकि मैं एक बार में प्रिंट कर सकूं। –

3

आसान::

using System; 
using System.IO; 
using System.Linq; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 

namespace WordMergeProject 
{ 
    public class Program 
    { 
     private static void Main(string[] args) 
     { 
      byte[] word1 = File.ReadAllBytes(@"..\..\word1.docx"); 
      byte[] word2 = File.ReadAllBytes(@"..\..\word2.docx"); 

      byte[] result = Merge(word1, word2); 

      File.WriteAllBytes(@"..\..\word3.docx", result); 
     } 

     private static byte[] Merge(byte[] dest, byte[] src) 
     { 
      string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString(); 

      var memoryStreamDest = new MemoryStream(); 
      memoryStreamDest.Write(dest, 0, dest.Length); 
      memoryStreamDest.Seek(0, SeekOrigin.Begin); 
      var memoryStreamSrc = new MemoryStream(src); 

      using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStreamDest, true)) 
      { 
       MainDocumentPart mainPart = doc.MainDocumentPart; 
       AlternativeFormatImportPart altPart = 
        mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId); 
       altPart.FeedData(memoryStreamSrc); 
       var altChunk = new AltChunk(); 
       altChunk.Id = altChunkId; 
           OpenXmlElement lastElem = mainPart.Document.Body.Elements<AltChunk>().LastOrDefault(); 
      if(lastElem == null) 
      { 
       lastElem = mainPart.Document.Body.Elements<Paragraph>().Last(); 
      } 


      //Page Brake einfügen 
      Paragraph pageBreakP = new Paragraph(); 
      Run pageBreakR = new Run(); 
      Break pageBreakBr = new Break() { Type = BreakValues.Page }; 

      pageBreakP.Append(pageBreakR); 
      pageBreakR.Append(pageBreakBr);     

      return memoryStreamDest.ToArray(); 
     } 
    } 
} 
+0

इस उत्तर में कोड से कुछ गायब है। – Boric

+0

आखरी एलेम के साथ आप क्या कर रहे हैं? ऐसा लगता है लेकिन सेट नहीं किया जाता है। – Rendition

संबंधित मुद्दे