2D array to table in c#? - c#

I need to put the data from this table into an array and then make the array print as a formatted table in the console.
Here's the table that I got my data from http://puu.sh/oqV8f/7d982f2665.jpg ; I just need to make the array output rows and columns instead of a list.
I have this so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Zumba1
{
class Zumba
{
static void Main(string[] args)
{ //Recreated the data in the table for the zumba section, added each row, and each column.
string[,] schedule = new string [8, 6] { { "1:00", "3:00", "5:00", "7:00", "TOTAL", "", },
{"Monday", "12", "10", "17", "22", "244", },
{"Tuesday", "11", "13", "17", "22", "252",},
{"Wednesday", "12", "10", "22", "22", "264",},
{"Thursday", "9", "14", "17", "22", "248",},
{"Friday", "12", "10", "21", "12", "220",},
{"Saturday", "12", "10", "5", "10", "148"},
{" ", " ", " ", " ", " ","1376",}};
foreach (string i in schedule)
{
Console.WriteLine(i.ToString());
}
Console.ReadKey();
}
}
}
Any Ideas?

Foreach on a [,] array gives you all elements as a list, as you noticed. In this case you need to output as follow:
for (int x0 = 0; x0 < schedule.GetLength(0); x0++)
{
for (int x1 = 0; x1 < schedule.GetLength(1); x1++)
{
Console.Write("{0}\t", schedule[x0, x1]);
}
Console.WriteLine();
}
Console.ReadKey();
If you want to use foreach for any reason, you can also declare your table as [][] array. But in both ways you have to create 2 loops:
string[][] schedule = new string[][] {
new string[] { "1:00", "3:00", "5:00", "7:00", "TOTAL", "", },
new string[] {"Monday", "12", "10", "17", "22", "244", },
new string[] {"Tuesday", "11", "13", "17", "22", "252",},
new string[] {"Wednesday", "12", "10", "22", "22", "264",},
new string[] {"Thursday", "9", "14", "17", "22", "248",},
new string[] {"Friday", "12", "10", "21", "12", "220",},
new string[] {"Saturday", "12", "10", "5", "10", "148"},
new string[] {" ", " ", " ", " ", " ","1376",}
};
foreach (string[] line in schedule)
{
foreach (string i in line)
Console.Write("{0}\t", i);
Console.WriteLine();
}

If you use a monospaced font in the console you can adjust where each thing displays by putting more spaces if necessary
For example for the members corresponding to the the 1st and 2nd row and 1st of second column this would be the thing to calculate:
Largest word is Wednesday that is 9 letters, on first row first column I should put 9 espaces as there would be a blank. Then you might put four spaces as a separator between columns, then for the second column you calculate that 1:00 is the largest string so for 12 you would add 2 extra spaces, and so on.
Using a tab instead of some spaces is also likely to work but if the table ends up having some string that is much larger than one in another column it won't work.
Hope it helps.

Got it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Zumba1
{
class Zumba
{
static void Main(string[] args)
{ //Recreated the data in the table for the zumba section, added each row, and each column. Worked on formatting.
string[,] schedule = new string[8, 6] { { "\t\t1:00", "3:00", "5:00", "7:00", "TOTAL", "", },
{"Monday", "\t12", "10", "17", "22", "$244", },
{"Tuesday", "\t11", "13", "17", "22", "$252",},
{"Wednesday", "12", "10", "22", "22", "$264",},
{"Thursday", "9", "14", "17", "22", "$248",},
{"Friday", "\t12", "10", "21", "12", "$220",},
{"Saturday", "12", "10", "5", "10", "$148"},
{" ", " ", " ", " ", " ","\t$1376",}};
//Nested for loops to print in a table-style format.
for (int i = 0; i < schedule.GetLength(0); i++)
{
for (int j = 0; j < schedule.GetLength(1); j++)
{
Console.Write(schedule[i, j] + "\t");
}
{
Console.WriteLine(i.ToString());
}
}
Console.ReadLine();
}
}
}
}

Related

Create JSON object from dynamic list from C#

I have a list of two dimensions dynamic as follows :
List<dynamic> tableContent = new List<dynamic>();
List<dynamic> rowHeader = new List<dynamic>();
rowHeader.add("First header");
rowHeader.add("Second header");
rowHeader.add("Third header");
tableContent.add(rowHeader);
for (int i = 0; i < 5; i++) {
List<dynamic> rowContent = new List<dynamic>();
rowContent.add("1");
rowContent.add("2");
rowContent.add("3");
tableContent.add(rowContent);
}
My tableContent is essentially
"First header", "Second header", "Third header"
"1" , "2" , "3"
"1" , "2" , "3"
"1" , "2" , "3"
"1" , "2" , "3"
"1" , "2" , "3"
I want to transform it into json as
[{"First header":"1","Second header":"2","Third header":"3"}
, {"First header":"1","Second header":"2","Third header":"3"}
, {"First header":"1","Second header":"2","Third header":"3"}
, {"First header":"1","Second header":"2","Third header":"3"}
, {"First header":"1","Second header":"2","Third header":"3"}]
How do I do this without changing my initial for loop to create my tableContent? (since I also need it for doing something else).
Thank you
Eko
Your tableContent is not essential to your example. Your tableContent right now is a List<List<string>> so it will be serialized as
[["First header","Second header","Third header"],["1","2","3"],["1","2","3"],["1","2","3"],["1","2","3"],["1","2","3"]]
If you need to keep your for loop unchanged, then write your own custom serializer. If you have no need in keeping for loop unchanged, form your data in right way. For an example:
var tableContent = new List<dynamic>();
for (int i = 0; i < 5; i++)
{
var rowContent = new Dictionary<dynamic, dynamic>();
rowContent["First header"] = "1";
rowContent["Second header"] = "2";
rowContent["Third header"] = "3";
tableContent.Add(rowContent);
}
Will result as:
[{"First header":"1","Second header":"2","Third header":"3"},{"First header":"1","Second header":"2","Third header":"3"},{"First header":"1","Second header":"2","Third header":"3"},{"First header":"1","Second header":"2","Third header":"3"},{"First header":"1","Second header":"2","Third header":"3"}]
P.S. if you have no special purposes, you can change your dynamic to strong types:
var tableContent = new List<Dictionary<string, string>>();
for (int i = 0; i < 5; i++)
{
var rowContent = new Dictionary<string, string>();
rowContent["First header"] = "1";
rowContent["Second header"] = "2";
rowContent["Third header"] = "3";
tableContent.Add(rowContent);
}
You can use newtonsoft - Json.NET to build (and parse) jsons.
It can be used in various ways, both "manually" and using automatic serialization. See here: Creating JSON.
The code below demonstrates how to use the "manual" approach to build the json in parallel to building your current data structure (like I understood you'd like to do):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
namespace Test
{
internal class Program
{
static void Main(string[] args)
{
List<List<string>> tableContent = new List<List<string>>();
JArray tableJson = new JArray(); // This will be the table json object we will build
string[] headerNames = { "First header", "Second header", "Third header" };
List<string> rowHeader = new List<string>();
rowHeader.Add(headerNames[0]);
rowHeader.Add(headerNames[1]);
rowHeader.Add(headerNames[2]);
tableContent.Add(rowHeader);
for (int i = 0; i < 5; i++)
{
List<string> rowContent = new List<string>();
JObject rowJson = new JObject(); // This will be the json for one row
string[] rowElements = { "1", "2", "3" };
Debug.Assert(rowElements.Length == headerNames.Length);
for (int j = 0; j < rowElements.Length; ++j)
{
rowContent.Add(rowElements[j]);
rowJson[headerNames[j]] = rowElements[j]; // Add the element to the row json
}
tableContent.Add(rowContent);
tableJson.Add(rowJson); // Add the row json to the table json
}
// Here tableJson contains the required json.
// Convert to string and print:
string tableJsonString = tableJson.ToString();
Console.WriteLine(tableJsonString);
}
}
}
Output:
[
{
"First header": "1",
"Second header": "2",
"Third header": "3"
},
{
"First header": "1",
"Second header": "2",
"Third header": "3"
},
{
"First header": "1",
"Second header": "2",
"Third header": "3"
},
{
"First header": "1",
"Second header": "2",
"Third header": "3"
},
{
"First header": "1",
"Second header": "2",
"Third header": "3"
}
]
Note: I changed the dynamic lists to have concrete types as this is more efficient.

How to save the entire contents of datagridview into the word document using office.word.interop.dll instead of spire.doc.dll?

How to implement the logic of the 1st block of code using Microsoft.Office.Interop.Word.dll?
Now I am using third party dll(Spire.Doc.dll), instead of Spire.Doc.dll. I want to use Microsoft.Office.Interop.Word.dll.
Please help me to implement this logic using the office word dll. Thanks
And in the 2nd block of codei tried to implement the logic og 1st block of code , i ahve achieved upto some extent however i coud not implement the complent logic of 1st block of code. it does not go well with the actual need. on button click event of more than once ( several times) all exported datagridview into word document are overlapping with each other so how to avoid the overlapping and save all tables properly(table right below the table)? please guide me to implement the above code logic.
All exported Datagridview content is getting merged in a single place (getting merged with each other) is there a way to save them in a well-organized way (recently exported table below the previously exported table)?
How to avoid overlapping? on button click event of more than once ( several times) all exported datagridview into word document are overlapping with each other so how to avoid the overlapping and save all tables properly(table right below the table)?
// 1st block of code (using Spire.Doc.dll)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.License;
using Spire.Doc.Fields;
namespace Export_Datagridview
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string filename;
public string Reportfile_path;
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("1");
dt.Columns.Add("2");
dt.Columns.Add("3");
dt.Columns.Add("4");
dt.Columns.Add("5");
dt.Columns.Add("6");
dt.Columns.Add("7");
dt.Columns.Add("8");
dt.Columns.Add("9");
dt.Columns.Add("10");
dt.Columns.Add("11");
dt.Columns.Add("12");
dt.Columns.Add("13");
dt.Columns.Add("14");
dt.Columns.Add("15");
dt.Columns.Add("16");
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13", 14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13", 14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dataGridView1.DataSource = dt;
}
private void button1_Click(object sender, EventArgs e)
{
export_datagridview();
}
private void export_datagridview()
{
string time = DateTime.Now.ToString("HH:mm:ss");
string date = DateTime.Today.ToShortDateString();
filename = Reportfile_path + "sample" + ".doc";
Document document = new Document();
try
{
document.LoadFromFile(filename, FileFormat.Doc);
}
catch
{
}
int xx = 0, yy = 0, section_number = 0;
Section section = new Section(document);
Paragraph paragraph = section.AddParagraph();
paragraph = section.Paragraphs.Count > 0 ? section.Paragraphs[0] : section.AddParagraph();
yy = document.Sections.Count;
if (yy == 0)
{
section_number = yy;
section = document.AddSection();
section = document.Sections[section_number];
}
else
{
section_number = yy - 1;
section = document.Sections[section_number];
}
xx = section.Tables.Count;
if (xx == 5)
{
section_number++;
section = document.AddSection();
section = document.Sections[section_number];
}
else
{
section = document.Sections[section_number];
}
paragraph = section.AddParagraph();
paragraph.AppendText("\t\t SOMETHING");
paragraph = section.AddParagraph();
paragraph = section.AddParagraph();
paragraph.AppendText("Something\t\t:\tsomething");
paragraph = section.AddParagraph();
paragraph.AppendText("something\t\t:\tsomething");
Add_Table(dataGridView1, filename, section);
document.SaveToFile(filename, FileFormat.Doc);
}
private void Add_Table(DataGridView dGV, string filename, Section section)
{
Spire.Doc.Table table = section.AddTable();
table.ResetCells(dGV.RowCount, dGV.ColumnCount);
table.ResetCells(dGV.RowCount + 1, dGV.ColumnCount);
// first row
TableRow row = table.Rows[0];
row.IsHeader = true;
row.Height = 22;
row.HeightType = TableRowHeightType.Exactly;
row.RowFormat.BackColor = Color.Gray;
for (int i = 0; i < dGV.ColumnCount; i++)
{
row.Cells[i].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
Paragraph p = row.Cells[i].AddParagraph();
p.Format.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Center;
TextRange txtRange = p.AppendText(Convert.ToString(dGV.Columns[i].HeaderText));
txtRange.CharacterFormat.Bold = true;
}
for (int r = 0; r < dGV.RowCount; r++)
{
TableRow dataRow = table.Rows[r + 1];
dataRow.Height = 22;
dataRow.HeightType = TableRowHeightType.Exactly;
dataRow.RowFormat.BackColor = Color.Empty;
for (int c = 0; c < dGV.ColumnCount; c++)
{
dataRow.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
row.Cells[c].Width = 80;
dataRow.Cells[c].Width = 80;
dataRow.Cells[c].AddParagraph().AppendText(Convert.ToString(dGV.Rows[r].Cells[c].Value));
}
}
}
}
}
// 2nd block of code (using Microsoft.Office.Interop.Word.dll)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Save_DataGridView_As_Word_Doc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string filename;
public string filepath;
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("1");
dt.Columns.Add("2");
dt.Columns.Add("3");
dt.Columns.Add("4");
dt.Columns.Add("5");
dt.Columns.Add("6");
dt.Columns.Add("7");
dt.Columns.Add("8");
dt.Columns.Add("9");
dt.Columns.Add("10");
dt.Columns.Add("11");
dt.Columns.Add("12");
dt.Columns.Add("13");
dt.Columns.Add("14");
dt.Columns.Add("15");
dt.Columns.Add("16");
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dt.Rows.Add(new object[] { "1", 2, "3", "4", "5", 6, "7", "8", "9", 10, "11", "12", "13",
14, "15", "16" });
dataGridView1.DataSource = dt;
}
private void button1_Click(object sender, EventArgs e)
{
save_datagridview(dataGridView1, filename);
}
public void save_datagridview(DataGridView DGV, string filename)
{
string time = DateTime.Now.ToString("HH:mm:ss");
string date = DateTime.Today.ToShortDateString();
filename = filepath + #"D:\datagridview" + ".docx";
var application = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
try
{
var originalDocument = application.Documents.Open(filename);
}
catch
{
}
if (DGV.Rows.Count != 0)
{
int RowCount = DGV.Rows.Count;
int ColumnCount = DGV.Columns.Count;
Object[,] DataArray = new object[RowCount + 1, ColumnCount + 1];
int r = 0; for (int c = 0; c <= ColumnCount - 1; c++)
{
for (r = 0; r <= RowCount - 1; r++)
{
DataArray[r, c] = DGV.Rows[r].Cells[c].Value;
}
}
application.ActiveDocument.PageSetup.Orientation =
Microsoft.Office.Interop.Word.WdOrientation.wdOrientLandscape;
dynamic orange = application.ActiveDocument.Content.Application.Selection.Range;
string otemp = "";
for (r = 0; r <= RowCount - 1; r++)
{
for (int c = 0; c <= ColumnCount - 1; c++)
{
otemp = otemp + DataArray[r, c] + "\t";
}
}
orange.Text = otemp;
object Separator = Microsoft.Office.Interop.Word.WdTableFieldSeparator.wdSeparateByTabs;
object ApplyBorders = true;
object AutoFit = true;
object AutoFitBehavior =
Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent;
orange.ConvertToTable(ref Separator, ref RowCount, ref ColumnCount, Type.Missing,
Type.Missing, ref ApplyBorders, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, ref AutoFit, ref AutoFitBehavior, Type.Missing);
orange.Select();
application.ActiveDocument.Application.Selection.Tables[1].Select();
application.ActiveDocument.Application.Selection.Tables[1].Rows.AllowBreakAcrossPages = 0;
application.ActiveDocument.Application.Selection.Tables[1].Rows.Alignment = 0;
application.ActiveDocument.Application.Selection.Tables[1].Rows[1].Select();
application.ActiveDocument.Application.Selection.InsertRowsAbove(1);
application.ActiveDocument.Application.Selection.Tables[1].Rows[1].Select();
application.ActiveDocument.Application.Selection.Tables[1].Rows[1].Range.Bold = 1;
application.ActiveDocument.Application.Selection.Tables[1].Range.Font.Name =
"Tahoma";
application.ActiveDocument.Application.Selection.Tables[1].Rows[1].Range.Font.Size =
14;
for (int c = 0; c <= ColumnCount - 1; c++)
{
application.ActiveDocument.Application.Selection.Tables[1].Cell(1, c + 1).Range.Text
= dataGridView1.Columns[c].HeaderText;
}
application.ActiveDocument.Application.Selection.Tables[1].set_Style("Grid Table 4 -
Accent 5");
application.ActiveDocument.Application.Selection.Tables[1].Rows[1].Select();
application.ActiveDocument.Application.Selection.Cells.VerticalAlignment =
Microsoft.Office.Interop.Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
foreach (Microsoft.Office.Interop.Word.Section section in
application.ActiveDocument.Application.ActiveDocument.Sections)
{
Microsoft.Office.Interop.Word.Range headerRange =
section.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
headerRange.Fields.Add(headerRange,
Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage);
headerRange.Text = "XYZ";
headerRange.Font.Size = 18;
headerRange.ParagraphFormat.Alignment =
Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;
}
//object start = 0, end = 0;
//Microsoft.Office.Interop.Word.Range rng1 = application.ActiveDocument.Range(ref start,
ref end);
//Microsoft.Office.Interop.Word.Range rng2 = application.ActiveDocument.Range(ref start,
ref end);
//rng1.SetRange(rng1.End, rng1.End);
//rng1.Text = "\t\t\t\t\t\t xyz\t :\t xyz ";
//rng2.SetRange(rng2.End, rng2.End);
//rng2.Text = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t zyz\t :\t xyz ";
application.ActiveDocument.Save();
application.Quit();
MessageBox.Show("Document created successfully !");
}
}
}
}
Before I start, it should be noted, as others have commented in the other questions you have posted, is that using “interop” is somewhat discouraged since there are other “free” third-party libraries that work just as well if not better. Example, interop is notoriously slow when dealing with large documents. However, I am also aware that in some cases you may not have an option. With that said, below is an example of adding tables to a Word document using interop.
In the current posted code, it is difficult to tell if you want to add the tables to a “new” document or add the tables to an existing document. The code below adds the tables to a “new” Word document.
Also, I recommend you break up the code to do certain things as this will make it easier to maintain and make changes. Example, having a method that simply “adds” the data from the grid to the table, without formatting the table. Then another method that formats the table and possibly another method to format the Word document. Mixing these things together in one method makes it difficult to maintain and make changes.
Given this, it would appear that a particular method could come in handy. This method would take two parameters… A DataGridView and a “Word Document.” This method would take the data from the given DataGridView and add the data to a new table and place that table to the end of the given Word Document.
As you may be aware of, dealing with ranges in Word can be cumbersome and placing the table in a particular paragraph will require extra work, however, it is doable. Because of this, the code below simply adds the table to the end of the document.
This method “Add_DGV_To_Doc” may look something like below. Following the code below, it first gets the range that is the end of the document… Word.Range range = doc.Bookmarks.get_Item(ref endOfDoc).Range; … a new paragraph will be added and the table will be placed in that new paragraph.
When creating the table to add to the Word document, an extra row is added for the header text. Then a new paragraph is added to the Word document. First a loop is started to set the header text for each column. Then the rows from the grid are added to the table. Lastly FormatTable() is called to format the new table. It appears your current posted code is doing unnecessary work by creating a string array then a string? All this appears unnecessary when you can simply read the data directly from the DataGridView.
private void Add_DGV_To_Doc(DataGridView dgv, Word.Document doc) {
object mis = System.Reflection.Missing.Value;
object endOfDoc = "\\endofdoc";
Word.Range range = doc.Bookmarks.get_Item(ref endOfDoc).Range;
Word.Table table = doc.Tables.Add(range, dgv.RowCount + 1, dgv.ColumnCount, ref mis, ref mis);
object prarRange = doc.Bookmarks.get_Item(ref endOfDoc).Range;
Word.Paragraph para = doc.Content.Paragraphs.Add(ref prarRange);
para.Range.Text = Environment.NewLine;
string value;
for (int col = 0; col < dgv.ColumnCount; col++) {
table.Cell(1, col + 1).Range.Text = dgv.Columns[col].HeaderText;
}
int tableRow = 2;
for (int row = 0; row < dgv.RowCount; row++) {
if (!dgv.Rows[row].IsNewRow) {
for (int col = 0; col < dgv.ColumnCount; col++) {
value = "";
if (dgv.Rows[row].Cells[col].Value != null) {
value = dgv.Rows[row].Cells[col].Value.ToString();
}
table.Cell(tableRow, col + 1).Range.Text = value;
}
tableRow++;
}
}
FormatTable(table);
}
Next is a method that formats the table.
private void FormatTable(Word.Table table) {
table.Rows[1].Range.Bold = 1;
table.Range.Font.Name = "Tahoma";
table.Rows[1].Range.Font.Size = 14;
table.set_Style("Grid Table 4 - Accent 5");
table.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
}
Next is a method to format the Word document.
private void SetHeadersForSections(Word.Document doc) {
foreach (Word.Section section in doc.Sections) {
Word.Range headerRange = section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
headerRange.Fields.Add(headerRange, Word.WdFieldType.wdFieldPage);
headerRange.Text = "XYZ";
headerRange.Font.Size = 18;
headerRange.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
}
}
Also, in your current posted code, it is unwise to ignore exceptions as the following code does…
try
{
var originalDocument = application.Documents.Open(filename);
}
catch
{
}
Having an “empty” catch is basically ignoring the error and continuing. Minimum you should display “what” the error is and/or deal with the error before continuing. This is frowned upon in just about any environment, and will get negative marks in an academic environment.
Lastly, it should be noted that when you use “com” objects such as a “Word Application” and a “Word Document” … it is YOUR responsibility to “release” the com objects your code creates. Your code does not do this, therefore, if you run the code numerous times, you will probably see numerous “Microsoft Word” processes still running even after you quit the program.
Therefore, your code should release these “com” objects before the code exits to avoid this resource leak. This can be seen in the “finally” code section of the try/catch/finally block below.
Putting all this together, the code below adds two (2) different grids to a Word document, and saves the Word document when button1 is clicked. The first dataGridView1 is filled with sixteen (16) rows and columns. The second datagridview2 is filled with ten (10) rows and columns.
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
DataTable dt = GetTable(16, 16);
dataGridView1.DataSource = dt;
dt = GetTable(10, 10);
dataGridView2.DataSource = dt;
}
private DataTable GetTable(int totCol, int totRow) {
DataTable dt = new DataTable();
for (int i = 0; i < totCol; i++) {
dt.Columns.Add("H " + (i + 1).ToString());
}
for (int i = 0; i < totRow; i++) {
dt.Rows.Add(GetRowArray(totCol));
}
return dt;
}
private object[] GetRowArray(int size) {
object[] obj = new object[size];
for (int i = 0; i < size; i++) {
obj[i] = (i + 1).ToString();
}
return obj;
}
private void button1_Click(object sender, EventArgs e) {
save_datagridview(dataGridView1);
}
public void save_datagridview(DataGridView DGV) {
string filename = #"D:\Test\datagridview.docx";
Word.Application app = null;
Word.Document doc = null;
try {
app = new Word.Application();
//app.Visible = true;
doc = app.Documents.Add();
doc.PageSetup.Orientation = Word.WdOrientation.wdOrientLandscape;
Add_DGV_To_Doc(dataGridView1, doc);
Add_DGV_To_Doc(dataGridView2, doc);
SetHeadersForSections(doc);
doc.SaveAs2(filename);
MessageBox.Show("Document created successfully !");
}
catch (Exception e) {
MessageBox.Show("ERROR: " + e.Message);
}
finally {
if (doc != null) {
Marshal.ReleaseComObject(doc);
}
if (app != null) {
app.Quit();
Marshal.ReleaseComObject(app);
}
}
}
Hope this helps.

How do I use string.replace() with chars?

So full disclousre this is homework. Anyway trying to make a morse code converter and I am just stuck on this last issue. I want to use chars and then use string.replace but I can't since my dictionary is all strings. I want to use chars though. So how would I get around this?
public void InputReader()
{
string inputForTranslating = inputForTranslator.Text;
Dictionary<string, string> morseDictionary = new Dictionary<string, string>
{
{ " ", " " }, { ",", "--..--" }, { ".", ".-.-.-" }, { "\\?", "..--.." }, { "0", "-----" }, { "1", ".----" }, { "2", "..---" }, { "3", "...--" },
{ "4", "....-" }, { "5", "....." }, { "6", "-...." }, { "7", "--..." }, { "8", "---.." }, { "9", "----." }, { "A", ".-" },
{ "B", "-..." }, { "C", "-.-." }, { "D", "-.." }, { "E", "." }, { "F", "..-." }, { "G", "--." }, { "H", "...." }, { "I", ".." },
{ "J", ".---" }, { "K", "-.-" }, { "L", ".-.." }, { "M", "---" }, { "N", "-." }, { "O", "---" }, { "P", ".--." }, { "Q", "--.-" },
{ "R", ".-." }, { "S", "..." }, { "T", "-" }, { "U", "..-" }, { "V", "...-" }, { "W", ".--" }, { "X", "-..-" }, { "Y", "-.--" },
{ "Z", "--.." }
};
char[] charArray = inputForTranslating.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
outPutTranslation.Text = outPutTranslation.ToString().Replace(morseDictionary.Keys, morseDictionary.Values); ////This is where the error occurs "cannot convert from 'System.Collections.Generic.Dictionary<string, string>.KeyCollection' to 'char'"
}
}
Replace takes strings/chars as parameters, not a collection of keys or values.
In this case, you don't even need the Replace, you can just add the values based on the keys.
Also, your outPutTranslation.Text will only have the last char.
Dictionary<string, string> morseDictionary = new Dictionary<string, string>
{
{ " ", " " }, { ",", "--..--" }, { ".", ".-.-.-" }, { "\\?", "..--.." }, { "0", "-----" }, { "1", ".----" }, { "2", "..---" }, { "3", "...--" },
{ "4", "....-" }, { "5", "....." }, { "6", "-...." }, { "7", "--..." }, { "8", "---.." }, { "9", "----." }, { "A", ".-" },
{ "B", "-..." }, { "C", "-.-." }, { "D", "-.." }, { "E", "." }, { "F", "..-." }, { "G", "--." }, { "H", "...." }, { "I", ".." },
{ "J", ".---" }, { "K", "-.-" }, { "L", ".-.." }, { "M", "---" }, { "N", "-." }, { "O", "---" }, { "P", ".--." }, { "Q", "--.-" },
{ "R", ".-." }, { "S", "..." }, { "T", "-" }, { "U", "..-" }, { "V", "...-" }, { "W", ".--" }, { "X", "-..-" }, { "Y", "-.--" },
{ "Z", "--.." }
};
string output = "";
foreach (char c in inputForTranslating.ToCharArray())
{
output += morseDictionary[c];
}
outPutTranslation.Text = output;
Well, string.Replace() works both with two chars or two strings. The error clearly states that morseDictionary.Keys is not a string. Neither is morseDictionary.Values. And it's right, they are the list of keys and values of the dictionary!
There's another mistake in that code. You're converting your input to a char array, and then iterating each character, and trying to replace there. Think about what it's doing:
If you have -.-, in the first iteration you will search over -, in the second over . and lastly over -. You'll never be able to find the K.
You should iterate your dictionary, and search each word in the whole string.
foreach(string key in morseDictionary) {
//for morse->letter
inputForTranslating=inputForTranslating.Replace(morseDictionary[key],key);
//for letter->morse
inputForTranslating=inputForTranslating.Replace(key,morseDictionary[key]);

How to deal with parallel arrays in LINQ?

I have 2 separate arrays (coming from Json, but that's not important). They are lined up... i.e. arr1[1] goes with arr2[1].
I want to create a list of Test objects with a few catches:
1) both arr1 and arr2 value can't be null
2) I'm only interested in indexes where the arr1 element is a multiple of 5
This is what I have so far:
class Test
{
public double d1;
public double d2;
}
class Program
{
static void Main(string[] args)
{
string[] arr1 = new string[] { "0", "2", "5", "7", "10", "11", null, "13", "15" };
string[] arr2 = new string[] { "11", "13", "56", "8", null, "44", "55", "66", "77" };
var v = arr1.Where(x => !String.IsNullOrEmpty(x)).Select(x => Double.Parse(x)).Where(x => (x % 5) == 0).Select((x, y) => new Test
{
d1 = x,
d2 = Double.Parse(arr2[y])
});
}
}
I'm not sure how to skip the ones where arr2 is null though and the alignment is getting messed up.
In order not to mess up alignment, you should first .Zip the two arrays. Then, if I understand correctly, those indices that have null as value in either array should be skipped, so you filter those out with .Where, then do the rest of your logic.
class Test
{
public double d1;
public double d2;
}
class Program
{
static void Main(string[] args)
{
string[] arr1 = new string[] { "0", "2", "5", "7", "10", "11", null, "13", "15" };
string[] arr2 = new string[] { "11", "13", "56", "8", null, "44", "55", "66", "77" };
var v = arr1
.Zip(arr2, (x, y) => new {x, y})
.Where(a => !string.IsNullOrEmpty(a.x) && !string.IsNullOrEmpty(a.y))
.Select(a => new Test { d1 = double.Parse(a.x), d2 = double.Parse(a.y) })
.Where(a => (a.d1 % 5) == 0);
// TODO, ready to enumerate over v.
}
}
You can filter by where condition as below.
class Program
{
static void Main(string[] args)
{
string[] arr1 = new string[] { "0", "2", "5", "7", "10", "11", null, "13", "15" };
string[] arr2 = new string[] { "11", "13", "56", "8", null, "44", "55", "66", "77" };
var v = arr1
.Zip(arr2, (x, y) => new { x, y })
.Where(a => !string.IsNullOrEmpty(a.x) && !string.IsNullOrEmpty(a.y))
.Select(a => new Test { d1 = double.Parse(a.x), d2 = double.Parse(a.y) })
.Where(a => (a.d1 % 5) == 0);
}
}

how do I replace numbers using regex?

I am using C# regex library to do some text find and replace.
I would like to change the following:
1 -> one
11 -> one one
123 -> one two three
for example, here's my code to replace ampersand:
string pattern = "[&]";
string replacement = " and ";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(text, replacement);
Edit
I found some great examples of .NET RegEx on MSDN:
http://msdn.microsoft.com/en-us/library/kweb790z.aspx
Since you're specifically asking for a regex, you could do something like this
var digits = new Dictionary<string, string> {
{ "0", "zero" },
{ "1", "one" },
{ "2", "two" },
{ "3", "three" },
{ "4", "four" },
{ "5", "five" },
{ "6", "six" },
{ "7", "seven" },
{ "8", "eight" },
{ "9", "nine" }
};
var text = "this is a text with some numbers like 123 and 456";
text = Regex.Replace(text, #"\d", x => digits[x.Value]);
which will give you
this is a text with some numbers like onetwothree and fourfivesix

Categories

Resources