using FastReport.RichTextParser; using FastReport.Utils; using System; using System.Drawing; using System.Text; namespace FastReport.Export.OoXML { /// /// Save /// public class RTF_ToDocX : IDisposable { private RichDocument doc; private Rectangle ext_padding = new Rectangle(); #region Private methods private string Quoted(long p) { return String.Concat("\"", p.ToString(), "\" "); } private string Quoted(string p) { return String.Concat("\"", p, "\" "); } private string GetRGBString(Color c) { return "\"#" + /*ExportUtils.ByteToHex(c.A) +*/ ExportUtils.ByteToHex(c.R) + ExportUtils.ByteToHex(c.G) + ExportUtils.ByteToHex(c.B) + "\""; } private string TranslateText(string text) { StringBuilder TextStrings = new StringBuilder(); int start_idx = 0; while (true) { int idx = text.IndexOfAny("&<>".ToCharArray(), start_idx); if (idx != -1) { TextStrings.Append(text.Substring(start_idx, idx - start_idx)); switch (text[idx]) { case '&': TextStrings.Append("&"); break; case '<': TextStrings.Append("<"); break; case '>': TextStrings.Append(">"); break; } start_idx = ++idx; continue; } TextStrings.Append(text.Substring(start_idx)); break; } return TextStrings.ToString(); } #endregion /// public void Dispose() { } /// public RTF_ToDocX(RichDocument doc) { this.doc = doc; } private void SaveDocumentBody(StringBuilder s) { foreach (Page p in doc.pages) SavePage(s, p, false); } private void SavePage(StringBuilder s, Page page, bool v) { SaveSequence(s, page.sequence, false); } private string GetFontName(RunFormat format) { string Name = "Arial"; int font_idx = (int)format.font_idx; if (font_idx < doc.font_list.Count) { RFont rf = doc.font_list[font_idx]; Name = rf.FontName; } return Name; } private void SaveRun(StringBuilder s, Run r) { s.Append(""); string FontName = GetFontName(r.format); s.Append(" "); if (r.format.bold) s.Append(""); if (r.format.strike) s.Append(""); if (r.format.italic) s.Append(""); if (r.format.underline) s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append("").Append(this.TranslateText(r.text)).Append(""); s.Append(""); } private void SavePargraph(StringBuilder s, RichTextParser.Paragraph par, bool InTable) { s.AppendLine(""); string halign = ""; switch (par.format.align) { case RichTextParser.ParagraphFormat.HorizontalAlign.Left: halign = "left"; break; case RichTextParser.ParagraphFormat.HorizontalAlign.Right: halign = "right"; break; case RichTextParser.ParagraphFormat.HorizontalAlign.Centered: halign = "center"; break; case RichTextParser.ParagraphFormat.HorizontalAlign.Justified: default: halign = "both"; break; } //switch (par.format.Valign) //{ // case RichTextParser.ParagraphFormat.VerticalAlign.Top: halign = "top"; break; // case RichTextParser.ParagraphFormat.VerticalAlign.Center: halign = "center"; break; // case RichTextParser.ParagraphFormat.VerticalAlign.Bottom: halign = "bottom"; break; // default: // halign = "top"; // break; //} s.Append(""); if (par.format.first_line_indent > 0) s.Append(""); #region Paragraph spacing int before_space = par.format.space_before + ext_padding.Top; int after_space = par.format.space_after + ext_padding.Bottom; s.Append(""); #endregion #region Paragraph indent if (ext_padding.Right + ext_padding.Left != 0) { s.Append(""); } #endregion s.Append(""); ; foreach (Run r in par.runs) SaveRun(s, r); s.AppendLine(""); } private void SaveTable(StringBuilder s, RichTextParser.Table tbl, bool InTable) { s.Append(""); // Table properties s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); s.Append(""); // Table grid s.Append(""); foreach (Column column in tbl.columns) { s.Append(""); } s.Append(""); foreach (TableRow row in tbl.rows) SaveRow(s, row); s.Append(""); } private void SaveRow(StringBuilder s, TableRow row) { s.Append(""); s.Append(""); foreach (RichObjectSequence seq in row.cells) { s.Append(""); s.Append(""); // Fix cell width s.AppendLine(""); SaveSequence(s, seq, true); s.AppendLine(""); } s.AppendLine(""); } private void SaveSequence(StringBuilder s, RichObjectSequence seq, bool InTable) { foreach (RichTextParser.RichObject robj in seq.objects) { switch (robj.type) { case RichTextParser.RichObject.Type.Paragraph: SavePargraph(s, robj.paragraph, InTable); break; case RichTextParser.RichObject.Type.Picture: // SkipPicture break; case RichTextParser.RichObject.Type.Table: SaveTable(s, robj.table, InTable); break; } } } /// /// Padding over ridh object /// public Rectangle Padding { get { return ext_padding; } set { ext_padding = value; } } /// /// This prperty keep RTF to DOC translation result, i.e. DOCX XML fragment /// public string DocX { get { StringBuilder s = new StringBuilder(); SaveDocumentBody(s); return s.ToString(); } } } }