/// <summary>
 /// Creates a response containing a comma-separated values (CSV) file created from the top level of a row tree. There will be one column for each merge
 /// field specified in the list of field names.
 /// </summary>
 public static EwfResponse CreateMergedCsvResponse( Func<string> extensionlessFileNameCreator, MergeRowTree rowTree, IEnumerable<string> fieldNames )
 {
     return Create(
         ContentTypes.Csv,
         new EwfResponseBodyCreator( writer => MergeOps.CreateTabularTextFile( rowTree, fieldNames, writer ) ),
         fileNameCreator: () => extensionlessFileNameCreator() + FileExtensions.Csv );
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Merges a row tree with a PDF document containing form fields.
 /// </summary>
 public static void CreatePdf(
     MergeRowTree rowTree, bool ensureAllFieldsHaveValues, string sourcePdfFilePath, Stream destinationStream,
     bool useLegacyBehaviorOfIgnoringInvalidFields = false)
 {
     // Use a memory stream because the stream may be read multiple times and we only want to access the file once.
     using( var sourcePdfStream = new MemoryStream( File.ReadAllBytes( sourcePdfFilePath ) ) )
         CreatePdf( rowTree, ensureAllFieldsHaveValues, sourcePdfStream, destinationStream, useLegacyBehaviorOfIgnoringInvalidFields );
 }
        /// <summary>
        /// Creates a response by merging a row tree with a Microsoft Word document. If you would like each row to be on a separate page, set the first paragraph in
        /// the input file to have a page break before it.
        /// </summary>
        public EwfResponse(
            Func<string> extensionlessFileNameCreator, MergeRowTree rowTree, bool ensureAllFieldsHaveValues, Action<Action<Stream>> inputStreamProvider)
            : this(ContentTypes.WordDoc,
				new EwfResponseBodyCreator(
					destinationStream => inputStreamProvider( inputStream => MergeOps.CreateMsWordDoc( rowTree, ensureAllFieldsHaveValues, inputStream, destinationStream ) ) ),
				fileNameCreator: () => extensionlessFileNameCreator() + FileExtensions.WordDoc)
        {
        }
        /// <summary>
        /// Creates a response by merging a row tree with a Microsoft Word document. If you would like each row to be on a separate page, set the first paragraph in
        /// the input file to have a page break before it.
        /// </summary>
        public EwfResponse( Func<string> extensionlessFileNameCreator, MergeRowTree rowTree, bool ensureAllFieldsHaveValues, string inputFilePath )
            : this(extensionlessFileNameCreator,
				rowTree,
				ensureAllFieldsHaveValues,
				writer => {
					using( var sourceDocStream = new MemoryStream( File.ReadAllBytes( inputFilePath ) ) )
						writer( sourceDocStream );
				})
        {
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Merges a row tree with a PDF document containing form fields.
        /// </summary>
        public static void CreatePdf(
            MergeRowTree rowTree, bool ensureAllFieldsHaveValues, MemoryStream sourcePdfStream, Stream destinationStream,
            bool useLegacyBehaviorOfIgnoringInvalidFields = false)
        {
            var streams = new List<Stream>();
            try {
                foreach( var row in rowTree.Rows ) {
                    var stream = new MemoryStream();
                    streams.Add( stream );

                    using( var sourcePdfMemoryStreamCopy = new MemoryStream() ) {
                        // Aspose has decided that in the new Facades PDF library, they will close your source stream for you when you call doc.Save.
                        sourcePdfStream.Reset();
                        sourcePdfStream.CopyTo( sourcePdfMemoryStreamCopy );

                        var doc = new Aspose.Pdf.Facades.Form( sourcePdfMemoryStreamCopy );
                        foreach( var mergeField in doc.FieldNames.Where( mergeField => !mergeField.StartsWith( "noMerge" ) ) ) {
                            var mergeValue = row.Values.SingleOrDefault( v => v.Name == mergeField );
                            if( mergeValue == null ) {
                                if( useLegacyBehaviorOfIgnoringInvalidFields )
                                    continue;
                                throw new MailMergingException( string.Format( "PDF document contains a merge field ({0}) that does not exist.", mergeField ) );
                            }

                            var mergeValueAsString = mergeValue as MergeValue<string>;
                            string value = null;
                            if( mergeValueAsString != null )
                                value = mergeValueAsString.Evaluate( ensureAllFieldsHaveValues );
                            if( value == null )
                                throw new MailMergingException( "Merge field " + mergeValue.Name + " evaluates to an unsupported type." );

                            doc.FillField( mergeValue.Name, value );
                        }
                        doc.Save( stream );
                    }
                }

                if( streams.Any() )
                    PdfOps.ConcatPdfs( streams, destinationStream );
            }
            finally {
                foreach( var i in streams )
                    i.Dispose();
            }
        }
Ejemplo n.º 6
0
        internal static ExcelFileWriter CreateExcelFileWriter( MergeRowTree rowTree, IEnumerable<string> fieldNames, bool useMsWordFieldNames )
        {
            var excelFile = new ExcelFileWriter();
            if( rowTree.Rows.Any() ) {
                foreach( var fieldName in fieldNames ) {
                    if( rowTree.Rows.First().Values.All( i => i.Name != fieldName ) ) {
                        // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                        throw new ApplicationException( "Merge field " + fieldName + " is invalid." );
                    }
                }

                var sheet = excelFile.DefaultWorksheet;
                sheet.AddHeaderToWorksheet(
                    fieldNames.Select( fieldName => rowTree.Rows.First().Values.Single( i => i.Name == fieldName ) )
                        .Select( mergeValue => useMsWordFieldNames ? mergeValue.MsWordName : mergeValue.Name.CamelToEnglish() )
                        .ToArray() );
                sheet.FreezeHeaderRow();
                foreach( var row in rowTree.Rows ) {
                    sheet.AddRowToWorksheet(
                        fieldNames.Select( fieldName => row.Values.Single( i => i.Name == fieldName ) ).Select(
                            mergeValue => {
                                var mergeValueAsString = mergeValue as MergeValue<string>;
                                string value = null;
                                if( mergeValueAsString != null )
                                    value = mergeValueAsString.Evaluate( false );
                                if( value == null ) {
                                    // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                                    throw new ApplicationException( "Merge field " + mergeValue.Name + " evaluates to an unsupported type." );
                                }

                                return value;
                            } ).ToArray() );
                }
            }
            return excelFile;
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Gets a merge field name tree of the fields that are supported by the CreateXmlDocument method.
 /// </summary>
 public static MergeFieldNameTree GetXmlSupportedMergeFields( MergeRowTree rowTree )
 {
     var firstRow = rowTree.Rows.First();
     return new MergeFieldNameTree(
         firstRow.Values.Where( mergeValueTypeIsSupportedInXml ).Select( i => i.Name ),
         childNamesAndChildren: firstRow.Children.Select( i => Tuple.Create( i.NodeName, GetXmlSupportedMergeFields( i ) ) ) );
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Gets the names of the merge fields from the top level of the specified row tree that are supported by the CreateTabularTextFile method.
 /// </summary>
 public static IEnumerable<string> GetTabularTextSupportedMergeFields( MergeRowTree rowTree )
 {
     return rowTree.Rows.First().Values.Where( mergeValueTypeIsSupportedInTabularText ).Select( v => v.Name );
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates an XML document from a row tree and writes it to a stream using UTF-8 encoding.
 /// </summary>
 // If we need to start generating XML on the fly for HTTP responses, it may make sense to create an overload of this method that takes an HttpResponse
 // object instead of a stream. This new overload would use the HttpResponse.Output property to obtain a TextWriter and then create the XmlWriter on top of
 // that instead of a stream. The advantage of this approach is that the encoding of the XML would then be determined by ASP.NET, which takes into account
 // any request headers the client may have sent that pertain to the desired encoding of the response.
 public static void CreateXmlDocument( MergeRowTree rowTree, MergeFieldNameTree fieldNameTree, Stream destinationStream )
 {
     using( var writer = XmlWriter.Create( destinationStream ) ) {
         writer.WriteStartDocument();
         writeRowTreeXmlElement( rowTree, fieldNameTree, writer );
         writer.WriteEndDocument();
     }
 }
 /// <summary>
 /// Sets the name and the merge row tree that will be used to draw the field tree. The name should be the plural name of the data type at the top level in
 /// the row tree, e.g. Clients.
 /// </summary>
 public void SetNameAndEmptyRowTree( string name, MergeRowTree emptyRowTree )
 {
     this.name = name;
     this.emptyRowTree = emptyRowTree;
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Merges a row tree with a Microsoft Word document. If you would like each row to be on a separate page, set the first paragraph in the input file to have
 /// a page break before it.
 /// </summary>
 public static void CreateMsWordDoc( MergeRowTree rowTree, bool ensureAllFieldsHaveValues, Stream inputStream, Stream destinationStream )
 {
     createMsWordDocOrPdfFromMsWordDoc( rowTree, ensureAllFieldsHaveValues, inputStream, destinationStream, true );
 }
 public static EwfResponse CreateMsWordDoc( MergeRowTree rowTree, bool ensureAllFieldsHaveValues, Action<Action<Stream>> inputStreamProvider )
 {
     return new EwfResponse( () => "MergedLetter", rowTree, ensureAllFieldsHaveValues, inputStreamProvider );
 }
 public static EwfResponse CreateMsWordDoc( MergeRowTree rowTree, bool ensureAllFieldsHaveValues, string inputFilePath )
 {
     return new EwfResponse( () => "MergedLetter", rowTree, ensureAllFieldsHaveValues, inputFilePath );
 }
 public static EwfResponse CreateExcelWorkbook(
     MergeRowTree rowTree, IEnumerable<string> fieldNames, string fileNameWithoutExtension, bool useMsWordFieldNames = false)
 {
     return new EwfResponse( () => fileNameWithoutExtension, rowTree, fieldNames, useMsWordFieldNames: useMsWordFieldNames );
 }
 /// <summary>
 /// Creates a response containing a single-sheet Excel workbook created from the top level of a row tree. There will be one column for each merge field
 /// specified in the list of field names. Each column head will be named by calling ToEnglishFromCamel on the merge field's name or using the Microsoft Word
 /// name without modification, the latter if useMsWordFieldNames is true.
 /// </summary>
 public EwfResponse( Func<string> extensionlessFileNameCreator, MergeRowTree rowTree, IEnumerable<string> fieldNames, bool useMsWordFieldNames = false )
     : this(extensionlessFileNameCreator, () => MergeOps.CreateExcelFileWriter( rowTree, fieldNames, useMsWordFieldNames ))
 {
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Creates a single-sheet Excel Workbook from the top level of a row tree and writes it to a stream. There will be one column for each merge field
 /// specified in the list of field names. Each column head will be named by calling ToEnglishFromCamel on the merge field's name or using the Microsoft Word
 /// name without modification, the latter if useMsWordFieldNames is true.
 /// </summary>
 public static void CreateExcelWorkbook( MergeRowTree rowTree, IEnumerable<string> fieldNames, Stream destinationStream, bool useMsWordFieldNames = false )
 {
     var excelFile = CreateExcelFileWriter( rowTree, fieldNames, useMsWordFieldNames );
     excelFile.SaveToStream( destinationStream );
 }
Ejemplo n.º 17
0
        private static void createMsWordDocOrPdfFromMsWordDoc(
            MergeRowTree rowTree, bool ensureAllFieldsHaveValues, Stream inputStream, Stream destinationStream, bool saveAsMsWordDoc)
        {
            var doc = new Aspose.Words.Document( inputStream );

            // This is a hack we need to do because Aspose changed MailMerge.Execute to only support a single level of data. Since we support multiple levels, i.e.
            // child data, we need to use MailMerge.ExecuteWithRegions, which associates the specified enumerator with the top level "table" in the document instead
            // of the document itself. See http://www.aspose.com/community/forums/thread/315734.aspx.
            var builder = new Aspose.Words.DocumentBuilder( doc );
            builder.MoveToDocumentStart();
            builder.InsertField( "MERGEFIELD TableStart:Main" );
            builder.MoveToDocumentEnd();
            builder.InsertField( "MERGEFIELD TableEnd:Main" );

            doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveUnusedRegions;
            doc.MailMerge.FieldMergingCallback = new ImageFieldMergingCallBack();
            try {
                doc.MailMerge.ExecuteWithRegions( new AsposeMergeRowEnumerator( "Main", rowTree.Rows, ensureAllFieldsHaveValues ) );
            }
            catch( InvalidOperationException e ) {
                // Aspose throws InvalidOperationException when there are problems with the template, such as a badly-formed region.
                throw new MailMergingException( e.Message );
            }
            doc.Save( destinationStream, saveAsMsWordDoc ? Aspose.Words.SaveFormat.Docx : Aspose.Words.SaveFormat.Pdf );
        }
 /// <summary>
 /// Creates a response containing a single-sheet Excel workbook created from the top level of a row tree. There will be one column for each merge field
 /// specified in the list of field names. Each column head will be named by calling ToEnglishFromCamel on the merge field's name or using the Microsoft Word
 /// name without modification, the latter if useMsWordFieldNames is true.
 /// </summary>
 public static EwfResponse CreateMergedExcelWorkbookResponse(
     Func<string> extensionlessFileNameCreator, MergeRowTree rowTree, IEnumerable<string> fieldNames, bool useMsWordFieldNames = false)
 {
     return CreateExcelWorkbookResponse( extensionlessFileNameCreator, () => MergeOps.CreateExcelFileWriter( rowTree, fieldNames, useMsWordFieldNames ) );
 }
Ejemplo n.º 19
0
        private static void writeRowTreeXmlElement( MergeRowTree rowTree, MergeFieldNameTree fieldNameTree, XmlWriter writer )
        {
            writer.WriteStartElement( rowTree.NodeName );
            foreach( var row in rowTree.Rows ) {
                writer.WriteStartElement( rowTree.XmlRowElementName );
                foreach( var fieldName in fieldNameTree.FieldNames ) {
                    var mergeValue = row.Values.SingleOrDefault( i => i.Name == fieldName );
                    if( mergeValue == null ) {
                        // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                        throw new ApplicationException( "Merge field " + fieldName + " is invalid." );
                    }

                    writer.WriteStartElement( mergeValue.Name );
                    if( mergeValue is MergeValue<string> )
                        writer.WriteValue( ( mergeValue as MergeValue<string> ).Evaluate( false ) );
                    else {
                        // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                        throw new ApplicationException( "Merge field " + mergeValue.Name + " evaluates to an unsupported type." );
                    }
                    writer.WriteEndElement();
                }

                foreach( var childNameAndFieldNameTree in fieldNameTree.ChildNamesAndChildren ) {
                    var childRowTree = row.Children.SingleOrDefault( i => i.NodeName == childNameAndFieldNameTree.Item1 );
                    if( childRowTree == null ) {
                        // Use ApplicationException instead of MailMergingException because the child names can easily be validated before this method is called.
                        throw new ApplicationException( "Child " + childNameAndFieldNameTree.Item1 + " is invalid." );
                    }
                    writeRowTreeXmlElement( childRowTree, childNameAndFieldNameTree.Item2, writer );
                }

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Merges a row tree with a Microsoft Word document and writes the result to a stream as a PDF document. If you would like each row to be on a separate
 /// page, set the first paragraph in the input file to have a page break before it.
 /// </summary>
 public static void CreatePdfFromMsWordDoc( MergeRowTree rowTree, bool ensureAllFieldsHaveValues, string inputFilePath, Stream destinationStream )
 {
     using( var sourcePdfStream = new MemoryStream( File.ReadAllBytes( inputFilePath ) ) )
         createMsWordDocOrPdfFromMsWordDoc( rowTree, ensureAllFieldsHaveValues, sourcePdfStream, destinationStream, false );
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Creates a comma-separated values (CSV) or tab-separated values file from the top level of a row tree. There will be one column for each merge field
        /// specified in the list of field names.
        /// </summary>
        public static void CreateTabularTextFile( MergeRowTree rowTree, IEnumerable<string> fieldNames, TextWriter destinationWriter, bool useTabAsSeparator = false )
        {
            if( !rowTree.Rows.Any() )
                return;

            foreach( var fieldName in fieldNames ) {
                if( rowTree.Rows.First().Values.All( i => i.Name != fieldName ) ) {
                    // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                    throw new ApplicationException( "Merge field " + fieldName + " is invalid." );
                }
            }

            var writer = useTabAsSeparator ? (TabularDataFileWriter)new TabDelimitedFileWriter() : new CsvFileWriter();
            foreach( var row in rowTree.Rows ) {
                writer.AddValuesToLine(
                    fieldNames.Select( fieldName => row.Values.Single( i => i.Name == fieldName ) ).Select(
                        mergeValue => {
                            var mergeValueAsString = mergeValue as MergeValue<string>;
                            if( mergeValueAsString != null )
                                return mergeValueAsString.Evaluate( false );

                            // Use ApplicationException instead of MailMergingException because the field names can easily be validated before this method is called.
                            throw new ApplicationException( "Merge field " + mergeValue.Name + " evaluates to an unsupported type." );
                        } ).Cast<object>().ToArray() );

                writer.WriteCurrentLineToFile( destinationWriter );
            }
        }
 /// <summary>
 /// Creates a merge field tree and sets the name and empty row tree.
 /// </summary>
 public MergeFieldTree( string name, MergeRowTree emptyRowTree )
 {
     SetNameAndEmptyRowTree( name, emptyRowTree );
 }