Adding multiple rows to a table in docx files with OpenXML - c#

I am using TemplateEngine.Docx, Template engine for generating Word docx in Visual Studio for C#. Basically I am trying to add multiple rows to a table in an edited word document using a for loop. However when I loop through the if statement it will just rewrite the data that was just read. Here is my code:
if (fieldName == "examrubric")
{
for (; ; )
{
Console.WriteLine("To enter a row to the tabel type 'yes'\n");
string choice = Console.ReadLine();
if (choice == "yes")
{
Console.WriteLine("Enter a value for the question number:\n");
string qnum = Console.ReadLine();
Console.WriteLine("Enter a value for what the question is out of:\n");
string score = Console.ReadLine();
Console.WriteLine("Enter a value for how much was scored:\n");
string qscore = Console.ReadLine();
Console.WriteLine("Enter a value for score:\n");
string score2 = Console.ReadLine();
Console.WriteLine("Enter the total mark:\n");
string total = Console.ReadLine();
valuesToFill = new Content(
new TableContent("examrubric")
.AddRow(
new FieldContent("qnum", qnum),
new FieldContent("score", score),
new FieldContent("qscore", qscore),
new FieldContent("score2", score2),
new FieldContent("total", total)));
}
else
{
break;
}
}
}

You could try the following code to write data to the docx file in the loop to avoid the rewrite the data .
static void Main(string[] args)
{
File.Copy("test1.docx", "OutputDocument.docx");
Console.WriteLine("To enter a row to the tabel type 'yes'\n");
string choice = Console.ReadLine();
Content valuesToFill = new Content(new TableContent("Team Members Table"));
for (int i = 0; i < 2; i++)
{
if (choice == "yes")
{
Console.WriteLine("Enter a value for the Name:\n");
string name = Console.ReadLine();
Console.WriteLine("Enter a value for the Role:\n");
string role = Console.ReadLine();
valuesToFill.Tables.First().AddRow(
new FieldContent("Name", name),
new FieldContent("Role", role)) ;
}
}
using (var outputDocument = new TemplateProcessor("OutputDocument.docx").SetRemoveContentControls(true))
{
outputDocument.FillContent(valuesToFill);
outputDocument.SaveChanges();
}
}
Tested result:

Related

Using lists within an if and foreach statement

I am creating a console application that is using user input to determine the data within two lists. Each list has the same data objects. They are name, rollNo, course and stream.
When all of the data has been inputted by the user then they are asked which stream information they would like to see. I then want to have the data that correlates with the stream input be displayed. For example if they want to see stream 1 then the information for the trainer and students on that stream should appear in the console.
This is my code below.
Student studentOne = new Student();
Console.WriteLine("Enter the Name of Student:");
studentOne.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of Student:");
studentOne.rollNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of Student:");
studentOne.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of Student:");
studentOne.stream = int.Parse(Console.ReadLine());
Student studentTwo = new Student();
Console.WriteLine("Enter the Name of Student:");
studentTwo.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of Student:");
studentTwo.rollNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of Student:");
studentTwo.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of Student:");
studentTwo.stream = int.Parse(Console.ReadLine());
Student studentThree = new Student();
Console.WriteLine("Enter the Name of Student:");
studentThree.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of Student:");
studentThree.rollNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of Student:");
studentThree.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of Student:");
studentThree.stream = int.Parse(Console.ReadLine());
var studentData = new List<Student>();
studentData.Add(studentOne);
studentData.Add(studentTwo);
studentData.Add(studentThree);
Trainer trainerOne = new Trainer();
Console.WriteLine("Enter the Name of the trainer:");
trainerOne.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of the trainer:");
trainerOne.trainNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of the trainer:");
trainerOne.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of the trainer:");
trainerOne.stream = int.Parse(Console.ReadLine());
Trainer trainerTwo = new Trainer();
Console.WriteLine("Enter the Name of the trainer:");
trainerTwo.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of the trainer:");
trainerTwo.trainNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of the trainer:");
trainerTwo.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of the trainer:");
trainerTwo.stream = int.Parse(Console.ReadLine());
Trainer trainerThree = new Trainer();
Console.WriteLine("Enter the Name of the trainer:");
trainerThree.name = Console.ReadLine();
Console.WriteLine("Enter the roll number of the trainer:");
trainerThree.trainNo = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the course of the trainer:");
trainerThree.course = Console.ReadLine();
Console.WriteLine("Enter the Stream of the trainer:");
trainerThree.stream = int.Parse(Console.ReadLine());
List<Trainer> trainerData = new List<Trainer>();
trainerData.Add(trainerOne);
trainerData.Add(trainerTwo);
trainerData.Add(trainerThree);
Console.WriteLine("Which stream details do you want to view?");
var streamInfo = int.Parse(Console.ReadLine());
if (streamInfo == 1)
{
foreach (var stream in trainerData)
{
}
}
class Student
{
public string name { get; set; }
public int rollNo { get; set; }
public string course { get; set; }
public int stream { get; set; }
}
class Trainer
{
public string name { get; set; }
public int trainNo { get; set; }
public string course { get; set; }
public int stream { get; set; }
}
Any help is appreciated.
Edit: I didn't make clear what I'm asking for. I'm not sure how to have the correct data show depending on what the stream input is. I have tried using an if statement and foreach statement but I don't know if this is the best approach.
Let's decompose the solution, let's start from reading integers:
private static int ReadInteger(string title, Func<int, bool> isValid = null) {
if (isValid is null)
isValid = x => true;
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (int.TryParse(Console.ReadLine(), out int result) && isValid(result))
return result;
Console.WriteLine("Invalid value, please, try again.");
}
}
private static string ReadString(string title, Func<string, bool> isValid = null) {
if (isValid is null)
isValid = x => true;
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
string result = Console.ReadLine();
if (isValid(result))
return result;
Console.WriteLine("Invalid value, please, try again.");
}
}
Then we can implement ReadStudent and ReadTrainer:
public static Student ReadStudent() {
return new Student() {
name = ReadString("Enter the Name of Student:", x => !string.IsNullOrWhiteSpace(x)),
rollNo = ReadInteger("Enter the roll number of Student:", x => x >= 0),
course = ReadString("Enter the course of Student:", x => !string.IsNullOrWhiteSpace(x)),
stream = ReadInteger("Enter the Stream of Student:", x => x >= 0),
};
}
public static Trainer ReadTrainer() {
return new Trainer() {
name = ReadString("Enter the Name of trainer:", x => !string.IsNullOrWhiteSpace(x)),
rollNo = ReadInteger("Enter the roll number of trainer:", x => x >= 0),
course = ReadString("Enter the course of trainer:", x => !string.IsNullOrWhiteSpace(x)),
stream = ReadInteger("Enter the Stream of trainer:", x => x >= 0),
};
}
Finally, we can create as many students and trainers as we want (note for loop - what if we want to enter 100 students?):
int students = 3;
int trainers = 3;
var studentData = new List<Student>(students);
for (int i = 0; i < students; ++i)
studentData.Add(ReadStudent());
var trainerData = new List<Trainer>(trainers);
for (int i = 0; i < trainers; ++i)
trainerData.Add(ReadTrainer());
Finally, to query the list by stream you can use Linq or good old loop or Linq:
int stream = ReadInteger("Which stream details do you want to view?");
foreach (Student s in studentData)
if (s.stream == stream)
Console.WriteLine($"Student {s.name} Roll No {s.rollNo}");
foreach (Trainer t in trainerData)
if (t.stream == stream)
Console.WriteLine($"Trainer {t.name} Roll No {t.rollNo}");

Can someone please tell me what is wrong this? and yes i just started learning c#

using System;
namespace superboombastic
{
class Program
{
static void Main(string[] args)
{
int [] a = {};
Console.Write("please enter your name: ");
string b = Console.ReadLine();
Console.WriteLine("Hi! " + b);
while (true)
{
Console.Write("Please enter Age: ");
int c = Convert.ToInt32(Console.ReadLine());
a = new int[c];
string e = "yes";
Console.Write("Do you want to continue? ");
string h = Console.ReadLine();
if (h != e)
{ break; }
}
Array.ForEach(a, Console.WriteLine);
}
}
}
What I want is the list to be printed after the user is done adding the values, but what is printing at the end is just a bunch of zeroes. So, please whosoever knows what I have done wrong, please enlighten me.
Below you have 2 examples, one with an array and other with a list
// With an array
int[] myArray = new int[] { 10, 20, 30 };
// Ex : Print with a For loop
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine(myArray[i]);
}
// Ex : Print with a Foreach loop
foreach (int item in myArray)
{
Console.WriteLine(item);
}
// With a list
List<int> myList = new List<int>() { 40, 50, 60 };
// Ex : Print with a For loop
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList.ElementAt(i));
}
// Ex : Print with a Foreach loop
foreach (int item in myList)
{
Console.WriteLine(item);
}
Please mark this answer as correct if that helps.
using System;
using System.Collections.Generic;
namespace superboombastic
{
class Program
{
static void Main(string[] args)
{
List<int> ageList = new List<int>();
Console.Write("please enter your name: ");
string userName = Console.ReadLine();
Console.WriteLine("Hi! " + userName);
bool exitLoop = false;
while (!exitLoop)
{
Console.Write("Please enter Age: ");
int age = Convert.ToInt32(Console.ReadLine());
ageList.Add(age);
string e = "yes";
Console.Write("Do you want to continue? ");
string h = Console.ReadLine();
if (h != e)
{
exitLoop = true;
}
}
foreach (var a in ageList)
{
Console.WriteLine(a);
}
}
}
}
I made some changes to the code based on what I believe you are trying to accomplish.
you were creating a new array in the loop each time, and then printing a new array of size age, which had nothing in it.
Instead let's create a list that you can add too each time the user adds an age to the list, then foreach over the list printing each value.
I also took the liberty in adding some more descriptive variables.

I'm trying to save array of strings to a txt file

I'm designing a program to save food recipes. The problem is when I save the ingredients of a new recipe it deletes the ingredients of the old recipe. I want both of them to be saved. Here's the code I use:
Console.WriteLine("Enter the path where your files will be saved: ");
string fileName = Console.ReadLine();
Console.WriteLine("Please enter the main ingrediant for your recipe: ");
string Main = Console.ReadLine();
Console.WriteLine("Please enter how many ingrediants in your recipe: ");
int Ingrediants = Convert.ToInt32(Console.ReadLine());
string[] a = new string[Ingrediants];
Recpies recipe1 = new Recpies(Main, Ingrediants);
recipe1.Ingrediants = new List<string[]>();
recipe1.TheMainIngrediant = Main;
Console.WriteLine("Please enter your ingrediants: ");
for (int i = 0; i < Ingrediants; i++)
{
a[i] = Console.ReadLine();
}
using (var file = System.IO.File.OpenText(fileName))
{
string line;
while ((line = file.ReadLine()?.Trim()) != null)
{
// skip empty lines
if (line == string.Empty)
{
recipe1.Ingrediants.Add(a);
recipe1.Saving(fileName, Ingrediants, a);
}
else
{
continue;
}
}
}
One possible way to achieve what you want is to use a combination between StreamWriter and File.AppendText, this is not going to overwrite the text you already save on that file instead of that is going to append the info at the end of the file (this example might be helpful: Append Text). Hope this helps! 👍
Just add true as second parameter
TextWriter tsw = new StreamWriter(fileName, true);

How do I search an int array vs a string array by comparing it to user input

How do I check if user input matches a number in an array?
I've learned to compare user input or search using a string array, however doing the same with an int array is not working for me.
zipCode[i] = 0;
int userZip = 0;
do
{
Console.WriteLine( "enter a 5 digit zip code to see if it is supported in our area." );
Console.WriteLine( );
Console.WriteLine( "Enter a 0 to exit the program" );
userZip = 0;
if ( userZip == zipCode[i] )
{
found = true;
if ( found )
{
Console.WriteLine( "We support zip code {0}", userZip ); ;
}
else
{
Console.WriteLine( "We do not support", userZip );
}
}
} while ( userZip != 0 );
Console.ReadLine( );
How do I check if user input matches a number in an array?
using System;
using System.Collections.Generic;
public class Program
{
static List<string> _zipCodes;
static Program()
{
_zipCodes = new List<string>() { "80205", "80225", "80210" };
}
static void Main(string[] args)
{
string userZip = string.Empty;
do
{
Console.WriteLine("enter a 5 digit zip code to see if it is supported in our area.");
Console.WriteLine();
Console.WriteLine("Enter a -1 to exit the program");
userZip = Console.ReadLine();
if (_zipCodes.Contains(userZip))//<---------------THAT WAY
{
Console.WriteLine("We support zip code {0}", userZip); ;
}
else
{
Console.WriteLine("We do not support zip code {0}", userZip);
}
} while (userZip != "-1");
}
}
How do I check if user input matches a number in an array?
I will answer this question, though I can't post an example using your sample code since it's incomplete and it's not exactly clear what it's supposed to do.
First, let's create a method that gets an integer from the user. This method will continually loop until the user enters a valid integer:
public static int GetIntFromUser(string prompt = null)
{
int input;
int row = Console.CursorTop;
int promptLength = prompt?.Length ?? 0;
do
{
Console.SetCursorPosition(0, row);
Console.Write(prompt + new string(' ', Console.WindowWidth - promptLength - 1));
Console.CursorLeft = promptLength;
} while (!int.TryParse(Console.ReadLine(), out input));
return input;
}
Now, we can use that method to get the zip code from the user:
int userZipCode = GetIntFromUser("Enter a 5 digit zip code to see if it's supported: ");
Now I'm assuming you have an array of zip codes that are supported. Perhaps something like:
private static int[] GetSeattleZipCodes()
{
return new []
{
98101, 98102, 98103, 98104, 98105, 98106, 98107, 98108, 98109, 98110,
98111, 98112, 98113, 98114, 98115, 98116, 98117, 98118, 98119, 98121,
98122, 98124, 98125, 98126, 98127, 98129, 98131, 98133, 98134, 98136,
98138, 98139, 98141, 98144, 98145, 98146, 98148, 98154, 98155, 98158,
98160, 98161, 98164, 98165, 98166, 98168, 98170, 98174, 98175, 98177,
98178, 98181, 98185, 98188, 98190, 98191, 98194, 98195, 98198, 98199
};
}
So, now we have an int user input, and an int[] of valid zip codes, so to see if the array of valid zip codes contains the user zip code, we can just use the Contains method:
int[] seattleZipCodes = GetSeattleZipCodes();
bool found = seattleZipCodes.Contains(userZipCode);
TheFastCat beat me, but:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
private static IEnumerable<string> zipCodes = new string[] { "90210", "94102", "98101", "80014" };
static void Main(string[] args)
{
Console.WriteLine("enter a 5 digit zip code to see if it is supported in our area, or '0' to exit");
do {
// Read next line
string userZip = Console.ReadLine().Trim();
// Exit program?
if (userZip == "0")
break;
// Validate input
if (userZip.Length != 5)
{
Console.WriteLine("ERROR: Zip code {0} is {1} characters; expected 5", userZip, userZip.Length);
continue;
}
int n;
bool isNumeric = int.TryParse(userZip, out n);
if (!isNumeric)
{
Console.WriteLine("ERROR: Zip code {0} must be numeric", userZip);
continue;
}
// Finally, see if our zip code matches a zip code in the list
bool found = zipCodes.Contains(userZip);
if (found)
{
Console.WriteLine("We support zip code {0}", userZip); ;
}
else
{
Console.WriteLine("We do not support " + userZip);
}
} while (true);
Console.WriteLine("Done: exiting program");
}
}
}
Note:
Initializing the list
Validating the input
Using IEnumerable.Contains() ... without necessarily messing with LINQ.
Use of "break" and "continue" to control the loop, without necessarily needing an extraneous variable.
An int array is Enumerable<int>, so you could just use Contains(): https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.contains?view=netframework-4.7.2
TheFastCat and Rufus L done great job.
I just want to add an example. Using 'var' datatypes makes things easy and durable as well in C#
This example demonstrates both 'int' and 'string' using var datatypes in both cases. Good luck haberjin.
static void Main(string[] args)
{
//var ZipCodes = new List<string>() { "04846", "40569", "76859","54896", "84623" }; // ZipCodes are stored as a string in a List
var ZipCodes = new List<int>() { 04846, 40569, 76859, 54896, 84623 }; // ZipCodes are stored as an int in a List
//var userZip = "";
var userZip = 0;
do
{
Console.WriteLine("Enter a 5 digit zip code to see if it is supported in our area.");
//userZip = Console.ReadLine(); // Enable to receive userZip as a string
userZip = int.Parse(Console.ReadLine()); // receive userZip as an int
if (ZipCodes.Contains(userZip))
{
Console.WriteLine("We support zip code {0}", userZip);
}
else
{
Console.WriteLine("We do not support", userZip);
}
//} while (userZip != "0");
} while (userZip != 0);
}

checking integers in String

I'm checking a string whether it has integers or anything else in function Parse().
Here is my Code
static public int input()
{
Console.WriteLine("Enter The Number Of Student You Want to get Record");
int x;
string inputString = Console.ReadLine();
if (int.TryParse(inputString, out x))
{
Console.WriteLine(inputString + " Is Integer");
return x= Convert.ToInt32(inputString);
}
else
{
input();
}
return x;
}
And full code is:
static void Main(string[] args)
{
int num = 0;
string[] names = new string[] { };
long[] fee = new long[] { };
string[] className = new string[] { };
do
{
Console.WriteLine("Enter Option You Want: \nA:Enter Student Record\nB:Display Student Record\nQ:Exit");
string option =null;
option =Console.ReadLine();
switch (option)
{
case "A":
case "a":
{
num = input();
names = new string[num];
fee = new long[num];
className = new string[num];
for (int i = 0; i < num; i++)
{
Console.WriteLine("Enter Name Of Student:{0}",i);
Console.Write("Enter Student Name: "); names[i] = Console.ReadLine();
Console.Write("Enter Student Fee: "); fee[i] = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Student Class Name: "); className[i] = Console.ReadLine();
}
break;
}
case "B":
case "b":
{
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine("Record of Student: {0}",i);
Console.WriteLine("Name: "+names[i]+ "\nFee: " + fee[i]+ "\nClass Name: " + className[i]);
//Console.WriteLine("Name: {0}\n Class Name: {1}\n Fee: {3}\n",names[i],className[i],fee[i]);
}
break;
}
case "Q":
case "q":
{
Environment.Exit(1);
break;
}
default:
{
Console.WriteLine("Invalid Option");
break;
}
}
} while (true);
}
But The problem is when I enters char instead of int and it works fine and calls itself again but if 2nd time or after 2nd time I input int then does not take input of students and instead it repeats the LOOP again.
So what's the problem, is problem in Input Function????
You could use a regular expression to find the INTs. Also you should call
return input();
instead of
input();
new method:
static public int input(){
Console.WriteLine("Enter The Number Of Student You Want to get Record");
string input = Console.ReadLine();
if (Regex.IsMatch(input, #"\d+"))
{
return int.Parse(Regex.Match(input, #"\d+").Value);
}
else
{
return input();
}
}
I'm assuming you're a student. I started out with C# doing the same stuff. Which I wouldn't do anymore but since you are doing it. I'd recommend using goto, making this method recursive is a no no.
static public int input()
{
Prompt:
Console.WriteLine("Enter The Number Of Student You Want to get Record");
int x;
string inputString = Console.ReadLine();
if (int.TryParse(inputString, out x))
{
Console.WriteLine(inputString + " Is Integer");
return x;
}
else
{
goto Prompt;
}
}

Categories