static Rect RenderTableHeader(C1WordDocument word, Font font, Rect rc, string[] fields) { // calculate cell width (same for all columns) Rect rcCell = rc; rcCell.Width = rc.Width / fields.Length; rcCell.Height = 0; // calculate cell height (max of all columns) foreach (string field in fields) { var height = word.MeasureString(field, font, rcCell.Width).Height; rcCell.Height = Math.Max(rcCell.Height, height); } rcCell.Height += 6; // add 6 point margin // render header cells var fmt = new StringFormat(); fmt.LineAlignment = VerticalAlignment.Center; foreach (string field in fields) { word.FillRectangle(Colors.Black, rcCell); word.DrawString(field, font, Colors.White, rcCell, fmt); rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0); } // update rectangle and return it return(WordUtils.Offset(rc, 0, rcCell.Height)); }
//--------------------------------------------------------------------------------- #region ** text flow static void CreateDocumentTextFlow(C1WordDocument word) { // load long string from resource file string text = "Resource not found..."; using (var sr = new StreamReader(DataAccess.GetStream("flow.txt"))) { text = sr.ReadToEnd(); } // content rectangle Rect rcPage = WordUtils.PageRectangle(word); // create two columns for the text var columnWidth = (float)(rcPage.Width - 30) / 2; word.MainSection.Columns.Clear(); word.MainSection.Columns.Add(new RtfColumn(columnWidth)); word.MainSection.Columns.Add(new RtfColumn(columnWidth)); // add title Font titleFont = new Font("Tahoma", 14, RtfFontStyle.Bold); Font bodyFont = new Font("Tahoma", 11); word.AddParagraph("Text Flow", titleFont, Colors.DarkOliveGreen, RtfHorizontalAlignment.Center); word.AddParagraph(string.Empty); // render string spanning columns and pages foreach (var part in text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) { word.AddParagraph(part, bodyFont, Colors.Black, RtfHorizontalAlignment.Justify); } }
//--------------------------------------------------------------------------------- #region ** paper sizes static void CreateDocumentPaperSizes(C1WordDocument word) { // landscape for first page bool landscape = true; word.Landscape = landscape; // add title Font titleFont = new Font("Tahoma", 24, RtfFontStyle.Bold); Rect rc = WordUtils.PageRectangle(word); word.AddParagraph(word.Info.Title, titleFont); var paragraph = (RtfParagraph)word.Current; paragraph.BottomBorderColor = Colors.Purple; paragraph.BottomBorderStyle = RtfBorderStyle.Dotted; paragraph.BottomBorderWidth = 3.0f; // create constant font and StringFormat objects Font font = new Font("Tahoma", 18); StringFormat sf = new StringFormat(); sf.Alignment = HorizontalAlignment.Center; sf.LineAlignment = VerticalAlignment.Center; word.AddParagraph("By default used Landscape A4", font); word.AddParagraph(string.Empty, font); // create one page with each paper size foreach (var fi in typeof(PaperKind).GetFields(BindingFlags.Static | BindingFlags.Public)) { // Silverlight/Phone doesn't have Enum.GetValues PaperKind pk = (PaperKind)fi.GetValue(null); // skip custom size if (pk == PaperKind.Custom) { continue; } // add new page for every page after the first one word.PageBreak(); // set paper kind and orientation var section = new RtfSection(pk); word.Add(section); landscape = !landscape; word.Landscape = landscape; // add some content on the page string text = string.Format("PaperKind: [{0}];\r\nLandscape: [{1}];\r\nFont: [Tahoma 18pt]", pk, word.Landscape); word.AddParagraph(text); paragraph = (RtfParagraph)word.Current; paragraph.SetRectBorder(RtfBorderStyle.DashSmall, Colors.Aqua, 2.0f); word.AddParagraph(string.Empty); } }
static Rect RenderTableRow(C1WordDocument word, Font font, Font hdrFont, Rect rcPage, Rect rc, string[] fields, DataRow dr) { // calculate cell width (same for all columns) Rect rcCell = rc; rcCell.Width = rc.Width / fields.Length; rcCell.Height = 0; // calculate cell height (max of all columns) rcCell = WordUtils.Inflate(rcCell, -4, 0); foreach (string field in fields) { string text = dr[field].ToString(); var height = word.MeasureString(text, font, rcCell.Width).Height; rcCell.Height = Math.Max(rcCell.Height, height); } rcCell = WordUtils.Inflate(rcCell, 4, 0); // add 4 point margin rcCell.Height += 2; // break page if we have to if (rcCell.Bottom > rcPage.Bottom) { word.PageBreak(); rc = RenderTableHeader(word, hdrFont, rcPage, fields); rcCell.Y = rc.Y; } // center vertically just to show how StringFormat fmt = new StringFormat(); fmt.LineAlignment = VerticalAlignment.Center; // render data cells foreach (string field in fields) { // get content string text = dr[field].ToString(); // set horizontal alignment double d; fmt.Alignment = (double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out d)) ? HorizontalAlignment.Right : HorizontalAlignment.Left; // render cell word.DrawRectangle(Colors.LightGray, rcCell); rcCell = WordUtils.Inflate(rcCell, -4, 0); word.DrawString(text, font, Colors.Black, rcCell, fmt); rcCell = WordUtils.Inflate(rcCell, 4, 0); rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0); } // update rectangle and return it return(WordUtils.Offset(rc, 0, rcCell.Height)); }
//--------------------------------------------------------------------------------- #region ** images static void CreateDocumentImages(C1WordDocument word) { // calculate page rect (discounting margins) Rect rcPage = WordUtils.PageRectangle(word); // load image into writeable bitmap BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = DataAccess.GetStream("borabora.jpg"); bi.EndInit(); var wb = new WriteableBitmap(bi); // center image on page preserving aspect ratio //word.DrawImage(wb, rcPage, ContentAlignment.MiddleCenter, Stretch.Uniform); word.DrawImage(wb, rcPage); }
void CreateDocumentVisualTree(C1WordDocument rtf, FrameworkElement targetElement) { // set up to render var font = new Font("Courier", 14); var img = new WriteableBitmap(CreateBitmap(targetElement)); // go render bool firstPage = true; foreach (Stretch stretch in new Stretch[] { Stretch.Fill, Stretch.None, Stretch.Uniform, Stretch.UniformToFill }) { // add page break if (!firstPage) { //rtf.NewPage(); } firstPage = false; // set up to render var alignment = ContentAlignment.TopLeft; //var rc = WordUtils.Inflate(rtf.PageRectangle, -72, -72); var sz = rtf.PageSize; var rc = new Rect(72, 72, sz.Width - 144, sz.Height - 144); rc.Height /= 2; // render element as image rtf.DrawString("Element as Image, Stretch: " + stretch.ToString(), font, Colors.Black, rc); rc = WordUtils.Inflate(rc, -20, -20); //rtf.DrawImage(img, rc, alignment, stretch); rtf.DrawImage(img, rc); rtf.DrawRectangle(Colors.Green, rc); rc = WordUtils.Inflate(rc, +20, +20); rtf.DrawRectangle(Colors.Green, rc); // move to bottom of the page rc = WordUtils.Offset(rc, 0, rc.Height + 20); // render element rtf.DrawString("Element as VisualTree, Stretch: " + stretch.ToString(), font, Colors.Black, rc); rc = WordUtils.Inflate(rc, -20, -20); rtf.DrawElement(targetElement, rc, alignment, stretch); rtf.DrawRectangle(Colors.Green, rc); rc = WordUtils.Inflate(rc, +20, +20); rtf.DrawRectangle(Colors.Green, rc); } }
static Rect RenderTable(C1WordDocument word, Rect rc, Rect rcPage, DataTable table, string[] fields) { // select fonts Font hdrFont = new Font("Tahoma", 10, RtfFontStyle.Bold); Font txtFont = new Font("Tahoma", 8); // build table //word.AddBookmark(table.TableName, 0, rc.Y); rc = WordUtils.RenderParagraph(word, "NorthWind " + table.TableName, hdrFont, rcPage, rc, false); // build table rc = RenderTableHeader(word, hdrFont, rc, fields); foreach (DataRow dr in table.Rows) { rc = RenderTableRow(word, txtFont, hdrFont, rcPage, rc, fields, dr); } // done return(rc); }
//--------------------------------------------------------------------------------- #region ** quotes static void CreateDocumentQuotes(C1WordDocument word) { // calculate page rect (discounting margins) Rect rcPage = WordUtils.PageRectangle(word); Rect rc = rcPage; // initialize output parameters Font hdrFont = new Font("Arial", 14, RtfFontStyle.Bold); Font titleFont = new Font("Arial", 24, RtfFontStyle.Bold); Font txtFont = new Font("Times New Roman", 10, RtfFontStyle.Italic); // add title var rcTop = WordUtils.RenderParagraph(word, word.Info.Title, titleFont, rcPage, rc); rc = rcTop; // build document foreach (string s in GetQuotes()) { string[] authorQuote = s.Split('\t'); // render header (author) var author = authorQuote[0]; rc.Y += 25; rc = WordUtils.RenderParagraph(word, author, hdrFont, rcPage, rc, true); // render body text (quote) string text = authorQuote[1]; rc.X = rcPage.X + 36; // << indent body text by 1/2 inch rc.Width = rcPage.Width - 40; rc = WordUtils.RenderParagraph(word, text, txtFont, rcPage, rc); rc.X = rcPage.X; // << restore indent rc.Width = rcPage.Width; rc.Y += 12; // << add 12pt spacing after each quote if (rc.Y > rcPage.Height) { word.PageBreak(); rc = rcTop; } } }
//--------------------------------------------------------------------------------- #region ** tables static void CreateDocumentTables(C1WordDocument word) { // get the data var ds = DataAccess.GetDataSet(); // calculate page rect (discounting margins) Rect rcPage = WordUtils.PageRectangle(word); Rect rc = rcPage; // add title Font titleFont = new Font("Tahoma", 24, RtfFontStyle.Bold); rc = WordUtils.RenderParagraph(word, word.Info.Title, titleFont, rcPage, rc, false); // render some tables RenderTable(word, rc, rcPage, ds.Tables["Customers"], new string[] { "CompanyName", "ContactName", "Country", "Address", "Phone" }); word.PageBreak(); rc = rcPage; RenderTable(word, rc, rcPage, ds.Tables["Products"], new string[] { "ProductName", "QuantityPerUnit", "UnitPrice", "UnitsInStock", "UnitsOnOrder" }); word.PageBreak(); rc = rcPage; RenderTable(word, rc, rcPage, ds.Tables["Employees"], new string[] { "FirstName", "LastName", "Country", "Notes" }); }
//--------------------------------------------------------------------------------- #region ** table of contents static void CreateDocumentTOC(C1WordDocument word) { // create pdf document word.Info.Title = "Document with Table of Contents"; // add title Font titleFont = new Font("Tahoma", 24, RtfFontStyle.Bold); Rect rcPage = WordUtils.PageRectangle(word); Rect rc = WordUtils.RenderParagraph(word, word.Info.Title, titleFont, rcPage, rcPage, false); rc.Y += 12; // create nonsense document var bkmk = new List <string[]>(); Font headerFont = new Font("Arial", 14, RtfFontStyle.Bold); Font bodyFont = new Font("Times New Roman", 11); for (int i = 0; i < 30; i++) { // create ith header (as a link target and outline entry) string header = string.Format("{0}. {1}", i + 1, BuildRandomTitle()); rc = WordUtils.RenderParagraph(word, header, headerFont, rcPage, rc, true, true); // save bookmark to build TOC later int pageNumber = 1; bkmk.Add(new string[] { pageNumber.ToString(), header }); // create some text rc.X += 36; rc.Width -= 36; for (int j = 0; j < 3 + _rnd.Next(20); j++) { string text = BuildRandomParagraph(); rc = WordUtils.RenderParagraph(word, text, bodyFont, rcPage, rc); rc.Y += 6; } rc.X -= 36; rc.Width += 36; rc.Y += 20; } // start Table of Contents word.PageBreak(); // start TOC on a new page //int tocPage = word.CurrentPage; // save page index (to move TOC later) //int tocPage = 1; // save page index (to move TOC later) rc = WordUtils.RenderParagraph(word, "Table of Contents", titleFont, rcPage, rcPage, true); rc.Y += 12; rc.X += 30; rc.Width -= 40; // render Table of Contents Pen dottedPen = new Pen(Colors.Gray, 1.5f); dottedPen.DashStyle = DashStyle.Dot; StringFormat sfRight = new StringFormat(); sfRight.Alignment = HorizontalAlignment.Right; rc.Height = bodyFont.Size * 1.2; foreach (string[] entry in bkmk) { // get bookmark info string page = entry[0]; string header = entry[1]; // render header name and page number word.DrawString(header, bodyFont, Colors.Black, rc); word.DrawString(page, bodyFont, Colors.Black, rc, sfRight); #if true // connect the two with some dots (looks better than a dotted line) string dots = ". "; var wid = word.MeasureString(dots, bodyFont).Width; var x1 = rc.X + word.MeasureString(header, bodyFont).Width + 8; var x2 = rc.Right - word.MeasureString(page, bodyFont).Width - 8; var x = rc.X; for (rc.X = x1; rc.X < x2; rc.X += wid) { word.DrawString(dots, bodyFont, Colors.Gray, rc); } rc.X = x; #else // connect with a dotted line (another option) var x1 = rc.X + word.MeasureString(header, bodyFont).Width + 5; var x2 = rc.Right - word.MeasureString(page, bodyFont).Width - 5; var y = rc.Top + bodyFont.Size; word.DrawLine(dottedPen, x1, y, x2, y); #endif // add local hyperlink to entry //rtf.AddLink("#" + header, rc); // move on to next entry rc = WordUtils.Offset(rc, 0, rc.Height); if (rc.Bottom > rcPage.Bottom) { word.PageBreak(); rc.Y = rcPage.Y; } } // move table of contents to start of document //var arr = new WordPage[rtf.Pages.Count - tocPage]; //rtf.Pages.CopyTo(tocPage, arr, 0, arr.Length); //rtf.Pages.RemoveRange(tocPage, arr.Length); //rtf.Pages.InsertRange(0, arr); }
//static string _extension = ".docx"; public static void HandleButtonClick(object sender, RoutedEventArgs e) { // get stream to save to var dlg = new SaveFileDialog(); dlg.FileName = "document"; dlg.DefaultExt = ".docx"; dlg.Filter = WordUtils.GetFileFilter(_extension); var dr = dlg.ShowDialog(); if (!dr.HasValue || !dr.Value) { return; } // get sender button var btn = sender as Button; // create document var word = new C1WordDocument(); word.Clear(); // set document info var di = word.Info; di.Author = "ComponentOne"; di.Subject = "C1.WPF.Word demo."; di.Title = (string)btn.Content; // create document switch (di.Title) { case "Quotes": CreateDocumentQuotes(word); break; case "Tables": CreateDocumentTables(word); break; case "Images": CreateDocumentImages(word); break; case "Paper Sizes": CreateDocumentPaperSizes(word); break; case "Table of Contents": CreateDocumentTOC(word); break; case "Text Flow": CreateDocumentTextFlow(word); break; case "Text": CreateDocumentText(word); break; case "Graphics": CreateDocumentGraphics(word); break; } // render footers // standard footer var text = string.Format("C1.WPF.Word: {0}, page {1} of {2}", di.Title, "|", "|"); var paragraph = new RtfParagraph(word.CurrentSection.Footer); paragraph.Alignment = RtfHorizontalAlignment.Right; int count = 0; foreach (var part in text.Split('|')) { if (!string.IsNullOrEmpty(part)) { paragraph.Add(new RtfString(part)); } switch (count) { case 0: paragraph.Add(new RtfPageField()); break; case 1: paragraph.Add(new RtfNumPagesField()); break; } count++; } word.CurrentSection.Footer.Add(paragraph); // this reopens each page and adds content to them (now we know the page count). //var font = new Font("Arial", 8, RtfFontStyle.Bold); //var fmt = new StringFormat(); //fmt.Alignment = HorizontalAlignment.Right; //fmt.LineAlignment = VerticalAlignment.Bottom; //for (int page = 0; page < rtf.Pages.Count; page++) //{ // rtf.CurrentPage = page; // var text = string.Format("C1.WPF.Word: {0}, page {1} of {2}", // di.Title, // page + 1, // rtf.Pages.Count); // rtf.DrawString( // text, // font, // Colors.DarkGray, // WordUtils.Inflate(rtf.PageRectangle, -72, -36), // fmt); //} // save document using (var stream = dlg.OpenFile()) { word.Save(stream, dlg.FileName.ToLower().EndsWith(".docx") ? FileFormat.OpenXml : FileFormat.Rtf); } MessageBox.Show("Word Document saved to " + dlg.SafeFileName); }