Writing into csv file display blank, using csvhelper - c#

Guys am trying to read a csv file from the view, get its data , format it and write back into an empty csv file. presently have been able to achieve the first approach, where the challenge is right now is writing back into an empty csv file created , but it happens that the csv file is always blank after writing in the file. can someone help me out if am missing anything. Note " am just reading and writing the field , have got nothing to do with the hearder because the csv file has no header" Am using csvhelper library.
if (file.ContentLength > 0)
{
string origin = "FORMATERCSV";
string destination = "FORMATERCSVDESTINATION";
string curretnDate = Convert.ToString(DateTime.Now.ToShortDateString().Replace(#"/", "_"));
var fileName = Path.GetFileName(file.FileName);
var pathfound = Server.MapPath( #"/" + "Content" + "/" + origin + "/" + curretnDate + "/");
var pathfoundDestination = Server.MapPath(#"/" + "Content" + "/" + destination + "/" + curretnDate + "/");
if (!Directory.Exists(pathfound)) Directory.CreateDirectory(pathfound);
if (!Directory.Exists(pathfoundDestination)) Directory.CreateDirectory(pathfoundDestination);
string PathToStore = string.Format(#"{0}\{1}", pathfound, fileName);
string PathToStoreDestination = string.Format(#"{0}\{1}", pathfoundDestination, fileName);
var path = Path.Combine(pathfound,fileName);
file.SaveAs(PathToStore);
file.SaveAs(PathToStoreDestination);
System.IO.File.WriteAllText(PathToStoreDestination,string.Empty);
StreamReader sr = new StreamReader(PathToStore);
CsvReader csvread = new CsvReader(sr);
csvread.Read();
var shedule = new Shedule()
{
RSA_PIN = csvread.GetField<string>(0),
EMPLOYEE_NAME = csvread.GetField<string>(1),
EMPLOYER_CONTRIBUTION = csvread.GetField<double>(2),
EMPLOYER_VC = csvread.GetField<double>(3),
EMPLOYEE_CONTRIBUTION = csvread.GetField<double>(4),
EMPLOYEE_VC = csvread.GetField<double>(5),
TOTAL_CONTRIBUTION = csvread.GetField<double>(6),
FROM_MONTH = csvread.GetField<string>(7),
FROM_YEAR = csvread.GetField<string>(8),
TO_MONTH = csvread.GetField<string>(9),
TO_YEAR = csvread.GetField<string>(10),
EMPLOYER_CODE = csvread.GetField<string>(11),
EMPLOYER_NAME = csvread.GetField<string>(12),
PTID = csvread.GetField<string>(13),
RECEIVED_DATE = csvread.GetField<string>(14),
};
StreamWriter sw = new StreamWriter(PathToStoreDestination);
CsvWriter scvwrite = new CsvWriter(sw);
scvwrite.WriteField(shedule.RSA_PIN);
scvwrite.WriteField(shedule.EMPLOYER_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYER_VC);
scvwrite.WriteField(shedule.EMPLOYEE_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYEE_VC);
scvwrite.WriteField(shedule.TOTAL_CONTRIBUTION);
scvwrite.WriteField(shedule.FROM_MONTH);
scvwrite.WriteField(shedule.FROM_YEAR);
scvwrite.WriteField(shedule.TO_MONTH);
scvwrite.WriteField(shedule.TO_YEAR);
scvwrite.WriteField(shedule.EMPLOYER_CODE);
scvwrite.WriteField(shedule.EMPLOYEE_NAME);
scvwrite.WriteField(shedule.PTID);
scvwrite.WriteField(shedule.RECEIVED_DATE);
scvwrite.NextRecord();
scvwrite.Flush();
// Gets field by position returning int
// var field = csv.GetField<int>(0);
}
return RedirectToAction("Index");
}

Several things could actually occure.
1) are you sure the file from the view is not empty?
2) If you use a break point when you instantiate your class Schedule. Do you get the data from the CSV.
3) Do you really need to do this 2 step, wouldn't it be better to directly write the content of the original file to the new file?
4) Last but not least don't forget to close your streamwriter or do like so :
using(var sw = new StreamWriter(PathToStoreDestination)){
CsvWriter scvwrite = new CsvWriter(sw);
scvwrite.WriteField(shedule.RSA_PIN);
scvwrite.WriteField(shedule.EMPLOYER_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYER_VC);
scvwrite.WriteField(shedule.EMPLOYEE_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYEE_VC);
scvwrite.WriteField(shedule.TOTAL_CONTRIBUTION);
scvwrite.WriteField(shedule.FROM_MONTH);
scvwrite.WriteField(shedule.FROM_YEAR);
scvwrite.WriteField(shedule.TO_MONTH);
scvwrite.WriteField(shedule.TO_YEAR);
scvwrite.WriteField(shedule.EMPLOYER_CODE);
scvwrite.WriteField(shedule.EMPLOYEE_NAME);
scvwrite.WriteField(shedule.PTID);
scvwrite.WriteField(shedule.RECEIVED_DATE);
scvwrite.Flush();
}
Doing so you don't even need to specify to flush.

using (var sw = new StreamWriter(PathToStoreDestination))
{
sw.AutoFlush = true;
CsvWriter scvwrite = new CsvWriter(sw);
scvwrite.WriteField(shedule.RSA_PIN);
scvwrite.WriteField(shedule.EMPLOYEE_NAME);
scvwrite.WriteField(shedule.EMPLOYER_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYER_VC);
scvwrite.WriteField(shedule.EMPLOYEE_CONTRIBUTION);
scvwrite.WriteField(shedule.EMPLOYEE_VC);
scvwrite.WriteField(shedule.TOTAL_CONTRIBUTION);
scvwrite.WriteField(shedule.FROM_MONTH);
scvwrite.WriteField(shedule.FROM_YEAR);
scvwrite.WriteField(shedule.TO_MONTH);
scvwrite.WriteField(shedule.TO_YEAR);
scvwrite.WriteField(shedule.EMPLOYER_CODE);
scvwrite.WriteField(shedule.EMPLOYER_NAME);
scvwrite.WriteField(shedule.PTID);
scvwrite.WriteField(shedule.RECEIVED_DATE);
scvwrite.NextRecord();
//scvwrite.Flush();
}

Related

c# Itextsharp copy content table / goto local page

I have a big problem and i hope you can help me out.
I have a PDF file which I split in more files.
Problem: There is a table content (goto page X), but in the new pdf files it doesnt work anymore.
I cant find a solution to copy this table content to the new pdf files.
For your understanding:
I have three pdf files which are equal.
PDF:
Page 1:
Text
Page 2:
Contenttable:
Content x Page 3 (Goto Page 3)
Content x Page 4 ""
content x Page 5 ""
...
...
I put all these pdf files together in one big pdf. (Content table still working)
And now, i will split these back in to single once (Content table not working)
My idea was to export the content table out of the original pdf(Where table content is still working) and to import it in the new once.
But i dont know how.
Second idea: search for keywords in the PDF and change the keyword to an goto local page action.
But i find no solution how i can do this.
However in the end i want to repair the table content in each single pdf file.
any ideas?
code so far:
PdfReader reader = null;
Document sourceDocument = null;
Document remote = null;
PdfCopy pdfCopyProvider = null;
PdfImportedPage importedPage = null;
PdfStamper stamp = null;
Chunk chunk = null;
reader = new PdfReader(path);
Seitenanzahl = reader.NumberOfPages;
sourceDocument = Document(reader.GetPageSizeWithRotation(startpage));
tmp = PdfTextExtractor.GetTextFromPage(reader, startpage);
string[] strsplit = tmp.Split(' ');
vorname = strsplit[4];
nachname = strsplit[5];
ort = strsplit[6];
perso = strsplit[7];
vorname = vorname.Replace("\n", "");
vorname = vorname.Replace(" ", "");
nachname = nachname.Replace("\n", "");
nachname = nachname.Replace(" ", "");
ort = ort.Replace("\n", "");
ort = ort.Replace(" ", "");
perso = perso.Replace("\n", "");
perso = perso.Replace(" ", "");
if (Directory.Exists("test/" + ort))
{
}
else
{
DirectoryInfo di = Directory.CreateDirectory("test/" + ort);
}
outputpdfpath = "test/" + ort + "/" + "p_" + ort + "_" + perso + "_" + vorname.ToLower() + "_" + nachname.ToLower() + "_hj1_booklet_2017" + ".pdf";
pdfCopyProvider = new PdfCopy(sourceDocument,
new FileStream(outputpdfpath, FileMode.Create, FileAccess.ReadWrite));
sourceDocument.Open();
for (int i = startpage; i <= endpage; i++)
{
importedPage = pdfCopyProvider.GetImportedPage(reader, i);
pdfCopyProvider.AddPage(importedPage);
}
sourceDocument.Close();
reader.Close();
}

How to avoid duplicate files (of different extensions) when auto generating new files

I have created a program which cleans access and error logs and then outputs them in a new file in the same directory. The input is in format .txt and the output is in format .csv - however it is giving me two output files, one in .csv format and one in .txt format(.txt file is empty) instead of just the .csv file? I can't understand why this is happening.
Below is the two ouput files as shown in the directory:
Below is the code which generates the new file with the unique name:
static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
{
var fileBase = Path.GetFileNameWithoutExtension(fileName);
var ext = Path.GetExtension(fileName);
// build hash set of filenames for performance
var files = new HashSet<string> (Directory.GetFiles(folder));
for (var index = 0; index < maxAttempts; index++)
{
// first try with the original filename, else try incrementally adding an index
var name = (index == 0)
? fileName
: String.Format("{0} ({1}){2}", fileBase, index, ext);
// check if exists
var fullPath = Path.Combine(folder, name);
if(files.Contains(fullPath))
continue;
// try to create the file
try
{
return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
}
catch (DirectoryNotFoundException) { throw; }
catch (DriveNotFoundException) { throw; }
catch (IOException)
{
}
}
throw new Exception("Could not create unique filename in " + maxAttempts + " attempts");
}
And finally the code below is the code which reads in the existing file and cleans it:
public static void readFile(string fileName)
{
using (var stream = CreateFileWithUniqueName(#"C:\Users\michael\Desktop\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\", fileName))
{
Console.WriteLine("Created \"" + stream.Name + "\"");
newFileName = stream.Name;
Globals.CleanedErrorFileName = newFileName;
}
string CSVfileName = Path.ChangeExtension(newFileName, ".csv");
StreamReader reader = new StreamReader(fileName);
StreamWriter writer = new StreamWriter(CSVfileName);
string line;
string personalIdentifier = new string(fileName.Take(4).ToArray());
string gender = fileName.Substring(fileName.Length - 5, 1);
string classification = fileName.Substring(fileName.Length - 8, 2);
string text = string.Empty;
while ((line = reader.ReadLine()) != null)
{
string[] cleanArray;
cleanArray = new string[5];
var result = line.Split('[')
.Select((element, index) => index % 2 == 0
? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
: new string[] { element })
.SelectMany(element => element).ToList();
cleanArray[0] = personalIdentifier;
cleanArray[1] = gender;
cleanArray[2] = classification;
cleanArray[3] = result[0];
cleanArray[4] = result[2];
cleanArray[4] = cleanArray[4].Substring(7);
cleanArray[4] = cleanArray[4].Replace("]", " ");
cleanArray[4] = cleanArray[4].Insert(15, ",");
cleanArray[3] = cleanArray[3].Remove(cleanArray[3].Length - 2);
cleanArray[4] = cleanArray[4].Substring(0, cleanArray[4].IndexOf(":") + 1);
//re-formatting the date so that it can be accepted by machine learning
var dateString = cleanArray[3];
var date = DateTime.ParseExact(dateString, "ddd MMM dd HH:mm:ss yyyy", CultureInfo.InvariantCulture);
var newDateString = date.ToString("yyyy-MM-dd HH:mm:ss");
//inserting the new date and time into the array
cleanArray[3] = newDateString;
//push each clean array onto the file that has been automatically created at the top
writer.WriteLine(string.Join(", ", cleanArray.Select(v => v.ToString())));
writer.WriteLine();
}
I'm hoping the issue is something small but i can't seem to find it!
Thanks in advance!!
This line is the culprit:
return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
At this point, the file name in fullPath still has .txt extension, this creates the empty .txt file. Then you change extension to .csv and do this:
StreamWriter writer = new StreamWriter(CSVfileName);
which creates the new .csv file
Also, both streams are never closed in your code.

SSIS 2015 Script task convert text file to UTF8 in C# or VB

I want to convert my resulting txt file into a UTF8 formatted file so I can load it into my Azure SQL DW via Polybase. It is required the source file be in UTF8.
MSDN has an "IO Streaming example" HERE works perfectly for a single job. I am trying to architect an SSIS solution for around 30 tables though. I believe using this method would cause a race condition where the PS script will be locked by 1 SSIS package when another SSIS package needs it.
I am a sql dev, not a .NET dev so please forgive me. How would one convert the above to an SSIS C# Script task assuming I know how to pass parameters into the Script task?
PowerShell Code from MSDN
#Static variables
$ascii = [System.Text.Encoding]::ASCII
$utf16le = [System.Text.Encoding]::Unicode
$utf8 = [System.Text.Encoding]::UTF8
$ansi = [System.Text.Encoding]::Default
$append = $False
#Set source file path and file name
$src = [System.IO.Path]::Combine("<MySrcFolder>","<MyUtf8stage>.txt")
#Set source file encoding (using list above)
$src_enc = $ascii
#Set target file path and file name
$tgt = [System.IO.Path]::Combine("<MyDestFolder>","<MyFinalstage>.txt")
#Set target file encoding (using list above)
$tgt_enc = $utf8
$read = New-Object System.IO.StreamReader($src,$src_enc)
$write = New-Object System.IO.StreamWriter($tgt,$append,$tgt_enc)
while ($read.Peek() -ne -1)
{
$line = $read.ReadLine();
$write.WriteLine($line);
}
$read.Close()
$read.Dispose()
$write.Close()
$write.Dispose()
Update
I found a similar post which I was able to tweak to my needs, I swear I searched high and low before posting. Anyway here is what IS working for me. If you see anyway to improve it please share:
public void Main()
{
//$Package::SourceSQLObject = tablename
//$Package::StageFile_DestinationFolderPath = rootpath eg "C:\temp\"
string path = (string)Dts.Variables["$Package::StageFile_DestinationFolderPath"].Value;
string name = (string)Dts.Variables["$Package::SourceSQLObject"].Value;
string from = Path.Combine(path, name) + ".csv";
string to = Path.ChangeExtension(from, "txt");
Dts.Log("Starting " + to.ToUpper(), 0, null);
using (StreamReader reader = new StreamReader(from, Encoding.ASCII, false, 10))
using (StreamWriter writer = new StreamWriter(to, false, Encoding.UTF8, 10))
{
while (reader.Peek() >= 0)
{
writer.WriteLine(reader.ReadLine());
}
}
Dts.TaskResult = (int)ScriptResults.Success;
Your code indicates that your are trying to convert an ASCII file to UTF-8 however that article also states the following:
As UTF-8 uses the same character encoding as ASCII PolyBase will also
support loading data that is ASCII encoded.
So my advice to you is to try the file first with Polybase, check for any conversion issues before you spend any time trying to convert the files.
var mySrcFolder = ""; // something from user variables?
var myUtf8stage = ""; // something from user variables?
var myFinalstage = ""; // something from user variables?
// Static variables
var ascii = System.Text.Encoding.ASCII;
var utf16le = System.Text.Encoding.Unicode;
var utf8 = System.Text.Encoding.UTF8;
var ansi = System.Text.Encoding.Default;
var append = false;
// Set source file path and file name
var src = System.IO.Path.Combine(
mySrcFolder,
String.Format("{0}.txt", myUtf8stage));
// Set source file encoding (using list above)
var src_enc = ascii;
// Set target file path and file name
var tgt = System.IO.Path.Combine(
mySrcFolder,
String.Format("{0}.txt", myFinalstage));
// Set target file encoding (using list above)
var tgt_enc = utf8;
using (var read = new System.IO.StreamReader(src, src_enc))
using (var write = new System.IO.StreamWriter(tgt, append, tgt_enc))
{
while (read.Peek() != -1)
{
var line = read.ReadLine();
write.WriteLine(line);
}
}
public void Main()
{
//$Package::SourceSQLObject = tablename
//$Package::StageFile_DestinationFolderPath = rootpath eg "C:\temp\"
string path = (string)Dts.Variables["$Package::StageFile_DestinationFolderPath"].Value;
string name = (string)Dts.Variables["$Package::SourceSQLObject"].Value;
string from = Path.Combine(path, name) + ".csv";
string to = Path.ChangeExtension(from, "txt");
Dts.Log("Starting " + to.ToUpper(), 0, null);
using (StreamReader reader = new StreamReader(from, Encoding.ASCII, false, 10))
using (StreamWriter writer = new StreamWriter(to, false, Encoding.UTF8, 10))
{
while (reader.Peek() >= 0)
{
writer.WriteLine(reader.ReadLine());
}
}
Dts.TaskResult = (int)ScriptResults.Success;

C# How to use a folder in a project

I've honestly been researching about this for hours, and I still haven't found anything close to what I am looking for.
Basically I created a folder in my project and called it "Files". Then I added a lot of actual files to that folder, and now I want to access them via a void, but I can't get the names of them.
I've tried to display the files in a message box (just for testing purposes), so I used this:
public static string[] GetResourceNames()
{
var asm = Assembly.GetEntryAssembly();
string resName = asm.GetName().Name + ".Files";
using (var stream = asm.GetManifestResourceStream(resName))
using (var reader = new System.Resources.ResourceReader(stream))
{
return reader.Cast<DictionaryEntry>().Select(entry => (string)entry.Key).ToArray();
}
}
But all it does is return an error saying the reader can't be null.
I'm trying to show it in a foreach loop like this:
foreach (string resourceName in GetResourceNames())
{
MessageBox.Show(resourceName);
}
but it shows nothing.
What I'm trying to do is this:
Assembly assembly = Assembly.GetExecutingAssembly();
int totalFiles = 17;
int currentFiles = 0;
foreach (var file in assembly.GetManifestResourceNames())
{
string extractPath = functions.pathToExtract + #"\" + file;
using (Stream s = assembly.GetManifestResourceStream(file))
using (BinaryReader r = new BinaryReader(s))
using (FileStream fs = new FileStream(extractPath, FileMode.OpenOrCreate))
using (BinaryWriter w = new BinaryWriter(fs))
w.Write(r.ReadBytes((int)s.Length));
currentFile.Invoke((MethodInvoker)delegate { currentFile.Text = "Installing : " + file + " ( " + currentFiles + " out of "+ totalFiles + " installed )"; });
currentFiles += 1;
}
This is what I'm trying to do, and this is code is successful, but it writes the file names as: SolutionName.Files.FileName.Extension and I only want it to write as FileName.Extension
What am I doing wrong here?
Well, a resource file is stored with the format you've specified: [Solution].[Folder].[File].[Extension].
Assuming all you really want to do is remove the initial [Solution].[Folder] from file names you can just use String.Replace.
Something like:
var fileName = file.Replace("[Solution].[Folder]", "");
Then use fileName for the currentFile.Text or for extractPath. Be mindful that I don't know what functions.pathToExtract + #"\" + file in your code produces at the moment, so it's a bit of a guess on my part, but I think this would produce a sensible path which could be used for extracting embedded resources.

How to copy file from one library to another library using CSOM?

I need to copy a particular file from one library to another library.
At first, need to check if file is existing in that library.
If Existing, then need to overwrite file content and new sharepoint version should be updated for that document.
I need to do this using c# CSOM and sharepoint version is 2013.
Thanks in advance :)
public static void CopyDocuments(string srcUrl, string destUrl, string srcLibrary, string destLibrary, Login _login)
{
// set up the src client
SP.ClientContext srcContext = new SP.ClientContext(srcUrl);
srcContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
srcContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// set up the destination context (in your case there is no needs to create a new context, because it would be the same library!!!!)
SP.ClientContext destContext = new SP.ClientContext(destUrl);
destContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
destContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// get the list and items
SP.Web srcWeb = srcContext.Web;
SP.List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
SP.ListItemCollection col = srcList.GetItems(new SP.CamlQuery());
srcContext.Load(col);
srcContext.ExecuteQuery();
// get the new list
SP.Web destWeb = destContext.Web;
destContext.Load(destWeb);
destContext.ExecuteQuery();
foreach (var doc in col)
{
try
{
if (doc.FileSystemObjectType == SP.FileSystemObjectType.File)
{
// get the file
SP.File f = doc.File;
srcContext.Load(f);
srcContext.ExecuteQuery();
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
if (doc.FileSystemObjectType == SP.FileSystemObjectType.Folder)
{
// load the folder
srcContext.Load(doc);
srcContext.ExecuteQuery();
// get the folder data, get the file collection in the folder
SP.Folder folder = srcWeb.GetFolderByServerRelativeUrl(doc.FieldValues["FileRef"].ToString());
SP.FileCollection fileCol = folder.Files;
// load everyting so we can access it
srcContext.Load(folder);
srcContext.Load(fileCol);
srcContext.ExecuteQuery();
foreach (SP.File f in fileCol)
{
// load the file
srcContext.Load(f);
srcContext.ExecuteQuery();
string[] parts = null;
string id = null;
if (srcLibrary == "My Files")
{
// these are doc sets
parts = f.ServerRelativeUrl.Split('/');
id = parts[parts.Length - 2];
}
else
{
id = folder.Name;
}
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + id + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
}
}
catch (Exception ex)
{
Log("File Error = " + ex.ToString());
}
}
}
Source: https://sharepoint.stackexchange.com/questions/114033/how-do-i-move-files-from-one-document-library-to-another-using-jsom
I strongly advise against using the approach suggested by Nikerym. You don't want to download the bytes only to upload them unmodified. It's slow and error-prone. Instead, use the built-in method provided by the CSOM API.
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt162553(v=office.15)?redirectedfrom=MSDN
var srcPath = "https://YOUR.sharepoint.com/sites/xxx/SitePages/Page.aspx";
var destPath = $"https://YOUR.sharepoint.com/sites/xxx/SitePages/CopiedPage.aspx";
MoveCopyUtil.CopyFileByPath(ctx, ResourcePath.FromDecodedUrl(srcPath), ResourcePath.FromDecodedUrl(destPath), false, new MoveCopyOptions());
ctx.ExecuteQuery();
You can configure the override behavior by adjusting the 4th and 5th arguments of the function signature.
[...]
bool overwrite,
MoveCopyOptions options
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt844930(v=office.15)

Categories