Intro
Excerpt |
---|
An AdventureWorks Product Catalog with formatting, tables, lists, nested data, and images. |
Create a product catalog by writing data into sections of an existing Word document. This sample demonstrates writing data from a database, formatting, nested Word lists, Word tables, and image insertion
Code
Code Block |
---|
private WordApplication wwapp;
private Document doc;
private Font charFormat;
// The three major product categories
string[] categories = { "Component", "Clothing", "Accessory" };
private bool bCategoriesOnNewPage = true;
// This DataTable will store all the product details
private DataTable data;
/// <summary>
/// Build the report with WordTemplate
/// </summary>
public void GenerateDocument()
{
// Create an instance of WordApplication and open the template document
wwapp = new WordApplication();
string templatePath = @"..\..\WordTemplateFiles\ProductCatalogTemplate.doc";
doc = wwapp.Open(templatePath);
// This document has three existing sections.
// The title page, the welcome letter page, and the
// blank section where the catalog items should be started.
Section secTitlePg = doc.Sections[0];
Section secWelcomePg = doc.Sections[1];
Section secCatalogPg = doc.Sections[2];
// Get a reference to the base style and set up a CharacterFormat
// object for use throughout this class.
NamedStyle baseStyle = doc.Styles[NamedStyle.BuiltIn.Normal];
charFormat = baseStyle.Font;
charFormat.FontName = "Arial";
// Add the current date to the first section
AddGeneratedDate(secTitlePg);
// Add a bulleted list to the second section.
// Bulleted items will be numbered.
AddList(secWelcomePg, true);
// Add the catalog items to the third section
// Populate data DataTable
// GetCSVData() is a helper method for parsing .csv files
data = GetCSVData(@"..\..\WordData\ProductCatalog2.csv");
AddCatalog(secCatalogPg);
// Save the document by streaming it to the client's browser
wwapp.Save(doc, @"..\..\WordOutputFiles\ProductCatalog_out.doc");
}
/// <summary>
/// Add the date string to the provided Range.
/// Date will be written in the form: "Jan 1, 2009"
/// </summary>
/// <param name="rng">Element into which the date should be written</param>
private void AddGeneratedDate(Element rng)
{
DateTime dt = DateTime.Now;
string datestring = String.Format("{0}/{1}/{2}", dt.Month, dt.Day, dt.Year);
rng.InsertTextAfter(datestring, false);
}
/// <summary>
/// Add the bulleted list of requested categories
/// and subcategories to the provided Range.
/// </summary>
/// <param name="rng">Element into which the list should be written</param>
/// <param name="bNumbered">Numbered (ordered) list</param>
private void AddList(Element rng, bool bNumbered)
{
// Add line breaks
rng.InsertParagraphAfter(null);
rng.InsertParagraphAfter(null);
// Create the List
List list = rng.InsertListAfter(bNumbered);
// Loop for every selected category
for (int iCat = 0; iCat < categories.Length; iCat++)
{
// Add the category text to the first level of the outline.
// Make the font bold-faced.
CharacterRun categoryRun =
list.AddEntry(0).InsertTextAfter(categories[iCat], charFormat);
categoryRun.Font.Bold = true;
// Get a list of product subcategories from the major
// category name.
string[] subCats = GetProductSubCategories(categories[iCat]);
// Loop for every subcategory in the current category
for (int iSubCat = 0; iSubCat < subCats.Length; iSubCat++)
{
// Add the subcategory text to the second
// level of the outline.
ListEntry li = list.AddEntry(1);
//li.LineNumberingAllowed = true;
li.InsertTextAfter(subCats[iSubCat], charFormat);
} // for each subcategory
} // for each category
}
/// <summary>
/// Add the main product catalog to the provided Range.
/// </summary>
/// <param name="rng">Element into which the catalog will be written</param>
private void AddCatalog(Element rng)
{
// Loop for every major category chosen
for (int iCat = 0; iCat < categories.Length; iCat++)
{
// Get the category name from the array categories
string catName = categories[iCat];
// Insert a table 1row x 1col. This table will
// hold the header text for every major category.
Table catTbl = doc.InsertTableAfter(1, 1);
// Write the major category name into the table cell.
// Set cell background and font appearance.
CharacterRun catRun =
catTbl[0, 0].InsertTextAfter(catName, charFormat);
catTbl[0, 0].Shading.BackgroundColor = System.Drawing.Color.Gray;
catRun.Font.Bold = true;
catRun.Font.Italic = true;
catRun.Font.FontSize = 26.0f;
// Get subcategory names for the current category
string[] subCats = GetProductSubCategories(catName);
// Marker
// // Loop once for every subcategory in the current category
for (int iSubCat = 0; iSubCat < subCats.Length; iSubCat++)
{
doc.InsertParagraphAfter(null);
string subCat = subCats[iSubCat];
// Insert a smaller header for the subcategory
CharacterRun subCatRun =
doc.InsertParagraphAfter(null).InsertTextAfter(subCat, charFormat);
subCatRun.Font.Bold = true;
subCatRun.Font.FontSize = 22.0f;
// GetProductCatalogData
// Get a list of products in the current subcategory
DataTable dtProducts = GetProductCatalogData(subCat);
// Loop for every product in the subcategory
//REFINE THIS COMMENT
foreach (DataRow dr in dtProducts.Rows)
{
// Insert a table to hold product data
Table prodTbl = doc.InsertTableAfter(4, 2);
// Merge the top row of cells
prodTbl[0, 0].FirstMerged = true;
prodTbl[0, 1].Merged = true;
// Add the product name and set font appearance
CharacterRun titleRun =
prodTbl[0, 0].InsertTextAfter(dr["Name"].ToString(), charFormat);
titleRun.Font.FontSize = 18.0f;
titleRun.Font.Bold = true;
titleRun.Font.Italic = true;
titleRun.Font.TextColor = System.Drawing.Color.Blue;
// Add product description to the next row
prodTbl[1, 0].InsertTextAfter(dr["Description"].ToString(), charFormat);
// InsertImageAfter method
if (dr["ThumbNailPhoto"].ToString() != "")
{
InlineImage image = prodTbl[1, 1].InsertImageAfter(@"..\..\WordImages\ProductCatalogImages\" + dtProducts.Rows[dtProducts.Rows.IndexOf(dr)]["ThumbNailPhoto"]);
double width = image.Width;
double height = image.Height;
Console.WriteLine("W: " + image.Width + ", H: " + image.Height);
image.Height=(int)( height//(2000 / width));
image.Width=2000;
Console.WriteLine("W: "+image.Width+", H: "+image.Height);
}
// Write the rest of the product details into the table
prodTbl[2, 0].InsertTextAfter("Product Number", charFormat).Font.Bold = true;
prodTbl[3, 0].InsertTextAfter(dr["ProductNumber"].ToString(), charFormat);
prodTbl[2, 1].InsertTextAfter("Price", charFormat).Font.Bold = true;
prodTbl[3, 1].InsertTextAfter("$" + dr["Price"].ToString(), charFormat);
}
}
// If it was chosen to put categories on new pages,
// AND if the last category hasn't just been written,
// add a section/page break.
if (bCategoriesOnNewPage && (iCat < categories.Length - 1))
{
Section sec = doc.CreateSectionAfter();
sec.Break = Section.BreakType.Page;
}
}
}
/// <summary>
/// Set document property metadata for the catalog document
/// </summary>
private void AddDocProperties()
{
// Get the DocumentProperties interface from Document
DocumentProperties docprops = doc.DocumentProperties;
// Set built-in DocumentProperties values
docprops.Author = "John Doe";
docprops.Comments = "A basic demonstration of OfficeWriter for Word";
docprops.Company = "SoftArtisans, Inc.";
docprops.Title = "Basic Word Document";
// Set custom DocumentProperties key/value pairs
docprops.SetCustomProperty("GeneratedBy", "SoftArtisans OfficeWriter for Word");
}
/// <summary>
/// Get a list of products for a subcategory.
/// </summary>
/// <param name="subCat">Subcategory name to look up</param>
/// <returns>DataTable of product from the provided subcategory</returns>
private DataTable GetProductCatalogData(string subCat)
{
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Description");
dt.Columns.Add("ProductNumber");
dt.Columns.Add("Price");
dt.Columns.Add("ThumbNailPhoto");
//find data
int iRow = 0;
while (iRow < data.Rows.Count)
{
if (data.Rows[iRow]["Subcategory"].ToString() == subCat)
{
dt.ImportRow(data.Rows[iRow]);
}
iRow++;
}
return dt;
}
/// <summary>
/// Get a list of subcategory names for the provided major category.
/// </summary>
/// <param name="cat">Category to look up</param>
/// <returns>Array of product subcategory strings</returns>
private string[] GetProductSubCategories(string cat)
{
ArrayList al = new ArrayList();
if (cat == "Clothing")
{
al.AddRange(new string[]{"Bib-Shorts","Caps","Gloves","Jerseys","Shorts","Socks","Tights","Vests"});
}
if (cat == "Component")
{
al.AddRange(new string[]{"Handlebars","Bottom Brackets","Brakes","Chains","Cranksets","Derailleurs","Forks","Headsets","Mountain Frames","Pedals","Road Frames","Saddles","Touring Frames","Wheels"});
}
if (cat == "Accessory")
{
al.AddRange(new string[]{ "Bike Racks","Bike Stands","Bottles and Cages","Cleaner","Fenders","Helmets","Hydration Packs","Lights","Locks","Panniers","Pumps","Tires and Tubes"});
}
return (string[])al.ToArray(typeof(string));
}
#region Utility Methods
//Uses CSV reader
System.Data.DataTable GetCSVData(string csvFileName)
{
DataTable dt;
using (GenericParserAdapter parser = new GenericParserAdapter(csvFileName))
{
parser.ColumnDelimiter = ',';
parser.FirstRowHasHeader = true;
dt = parser.GetDataTable();
}
return dt;
}
#endregion
|
Downloads
Template: ProductCatalogTemplate.doc
Output: ProductCatalog_out.doc