2016-05-27 3 views
0

私が取り組んでいるプロジェクトでは、私たちのチームが通常文書を生成するために使用しない方法を調べています。通常、ActiveReportsを使用してクライアントに提供するPDFを生成しますが、これはペーパーサイズのためにオプションではありません。重大は8.5インチx 11インチブラウザ側のPDFプラグイン、または当社がサポートしているプリンタが含まれます。Open XMLで複数ページの文書をデータのリストから生成

私がしようとしている具体的なことは、1 ... n 4 "x6"のインデックスカードを使用してドキュメントを作成することです。上記のように、私は生成する必要があるデータエントリの可変数を持つことができます。

私が過去にオープンXMLを使用しました唯一の方法は、テンプレートを取る私が注射したかったデータとキーワードを置き換え、その後、以下のように、クライアント次第、結果の文書を提供することです:

レポートクラス:

public class ThingReport : IDisposable 
{ 
    #region Variables/Properties 

    private readonly string _templatePath = string.Empty; 
    private MemoryStream _reportStream; 

    #endregion Variables/Properties 

    #region Constructor 

    public ThingReport(string templatePath) 
    { 
     _templatePath = templatePath; 
    } 

    #endregion Constructor 

    #region Methods 

    public void Dispose() 
    { 
     _reportStream.Dispose(); 
    } 

    public void RunReport(IList<Thing> things) 
    { 
     _reportStream = new MemoryStream(); 

     using (FileStream fs = File.OpenRead(_templatePath)) 
     { 
      fs.CopyTo(_reportStream); 
      _reportStream.Seek(0x00000000, SeekOrigin.Begin); 
      fs.Close(); 
     } 

     using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(_reportStream, true)) 
     { 
      // Set basic properties of the document... 
      pkgDoc.PackageProperties.Creator = "My App"; 
      pkgDoc.PackageProperties.Created = DateTime.Now; 
      pkgDoc.PackageProperties.Title = "Some document"; 
      pkgDoc.PackageProperties.ContentType = "application/msword"; 

      // Read the full document text, in prep for editing... 
      string docText; 
      using (StreamReader sr = new StreamReader(pkgDoc.MainDocumentPart.GetStream())) 
      { 
       docText = sr.ReadToEnd(); 
       sr.Close(); 
      } 

      // Replace the recipient. 
      // Source: https://msdn.microsoft.com/en-us/library/office/bb508261.aspx 
      Regex recipientRegex = new Regex("«Recipient»"); 
      docText = recipientRegex.Replace(docText, things[0].PersonName); 

      // Template has 3 fields in it; replace those fields with details of child data. 
      for (int i = 0; i < 3; i++) 
      { 
       string presentedDate = string.Empty; 
       string presentedNotes = string.Empty; 
       if (i <= things.Count - 1) 
       { 
        var thing = things[i]; 
        presentedDate = thing.thingDate.ToString("MM/dd/yyyy"); 
        presentedNotes = thing.Notes; 
       } 

       string dateReplaceText = string.Format("«ThingDate{0}»", i + 1); 
       Regex dateRegex = new Regex(dateReplaceText); 
       docText = dateRegex.Replace(docText, presentedDate); 

       string noteReplaceText = string.Format("«ThingNote{0}»", i + 1); 
       Regex noteRegex = new Regex(noteReplaceText); 
       docText = noteRegex.Replace(docText, presentedNotes); 
      } 

      // Write the modified document to the stream. 
      using (StreamWriter sw = new StreamWriter(pkgDoc.MainDocumentPart.GetStream(FileMode.Create))) 
      { 
       sw.Write(docText); 
       sw.Close(); 
      } 

      // Close the unmanaged resource! 
      pkgDoc.Close(); 
     } 
    } 

    public byte[] Export() 
    { 
     return _reportStream.ToArray(); 
    } 

    #endregion Methods 
}  

は私も一度に複数のデータエントリ間でWordテンプレートを使用しようとしたことがありません。これは私のチームの他のメンバーと同じ経験を持っている技術なので、私が行っているのと同じくらい正確に知っているので、これをどうやって行うのか尋ねることはできません。

私はOpen XML API for word documentsと、これを行うためのOpen XML APIの入手方法に関する他の必要なGoogleの検索を調べました...しかし、私は何の意味も分かりませんでした。

質問:私はメンバーの数が可変でList<Thing>を取る、とメンバーの数と同じページ数を持つ文書を生成するために、MS Wordのテンプレートを取るためにオープンXMLを使用することができますどのような方法では、すべて同じ形式を使用していますか?

+0

実際には、最初に行うべきことは、Word UIで結果を最もうまく取得する方法を理解することです。これは、Wordのビルトイン機能を使用してこれを実現する方法を分析することを意味します。これは、Open XML(またはオートメーション化されていても違いはありません)で使用するものですからです。たとえば、これは表形式で、アウトライン形式であるべきですか?ページがどのように壊れているかを決定するには - Wordには、スムーズなフローを得るためにスタイルに統合できる形式設定があります。他にどんなフォーマットが必要ですか? –

+0

便利な書式を取得したら、すべての要素(スタイルを含む)を含む最小限のドキュメントを作成します。そのドキュメントを保存し、Open XML SDK生産性ツールで開きます。それは、あなたがそのツールを使用したいならば、それを生成するOpen XML SDKコードだけでなく、ドキュメントを構成する根本的なWord Open XMLを表示します。それはあなたに出発点を与えるはずです。そして、一度あなたはおそらくあなたのリストデータを "変換"する方法を教える基になるXMLを参照してください... –

+0

私はあなたが実際に私の質問を読むとは思わない。私はツールをダウンロードしてテンプレート文書を開いていたのですが、私は単一のページを取って、必要なだけ何度もそのページを複製し、それらのページ上のプレースホルダーのテキストを置き換えるための明確な方法ではなく、私のオブジェクトの詳細と一緒に。 **多分** Open XMLは、私がしようとしているものに対して適切な技術ではありません。私はそれについて多くは分かりませんが、私がやっていることは可能であるか不可能であるかを知りたい。 –

答えて

2

あなたのThing /オブジェクトのメンバーとマッピングして、リストで差し込み印刷を実行するための数のマージフィールドを持つワードテンプレートを作成することをお勧めします。

DocIO Syncfusionのライブラリを使用すると、非常に簡単に達成できます。 DocIOは、Word 2003/2007/2010/2013/2016ファイルを読み書きする.NETライブラリです。あなたが資格があれば、community license programを通してコントロールの全スイートを無料で(商用アプリケーションも)利用できます。コミュニティライセンスは、制限や透かしのない完全な製品です。

たとえば、以下のようにWord文書テンプレートを作成してマージフィールドを作成し、顧客(リスト)の詳細のリストがあるとします。

Input Word template

ステップ1:Syncfusion.DocIO.Base、Syncfusion.Compression.BaseとSyncfusion.OfficeChart.Base
への参照を追加します。あなたが追加することができますコンソールアプリケーション
ステップ2を作成します。 NuGetを使ってプロジェクトを参照することもできます。
ステップ3:&に次のコードスニペットを貼り付けます。入力語のテンプレートを正しく参照してください。

このコードは、要件/要件ごとにドキュメントを生成し、結果として得られるWordドキュメントに別のページを生成します。

Download Demo

using System.Collections.Generic; 
using Syncfusion.DocIO.DLS; 
using Syncfusion.DocIO; 

namespace DocIO_MailMerge 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     List<Customer> customers = new List<Customer>(); 
     customers.Add(new Customer("Maria", "Anders", "[email protected]", "USA")); 
     customers.Add(new Customer("Ana", "Trujillo", "[email protected]", "USA")); 
     customers.Add(new Customer("Antonio", "Moreno", "[email protected]", "UK")); 
     customers.Add(new Customer("Thomas", "Hardy", "[email protected]", "Mexico")); 

     using (WordDocument wordDocument = new WordDocument(@"Template.docx")) 
     { 
      wordDocument.MailMerge.Execute(customers); 
      wordDocument.Save("Result.docx", FormatType.Docx); 
     } 

     System.Diagnostics.Process.Start("Result.docx"); 
    } 
} 
class Customer 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MailID { get; set; } 
    public string Country { get; set; } 
    public Customer(string firstName, string lastName, string emailID, string country) 
    { 
     FirstName = firstName; 
     LastName = lastName; 
     MailID = emailID; 
     Country = country; 
    } 
} 
} 

注:私はSyncfusionのために働きます。

関連する問題