C# VS2005 Convert Pipe Delimited .TXT to Excel Workbook .XLS - c#

I am using VS2005 C# and im trying to convert a pipe delimited text file to excel workbook format. Below is my code:
public partial class TextToExcel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SaveAsExcelBtn_Click(object sender, EventArgs e)
{
string xlExtension = ".csv";
string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss") + xlExtension;
// Before attempting to import the file, verify
// that the FileUpload control contains a file.
if (TextFile.HasFile)
{
// Get the name of the Excel spreadsheet.
string strFileName = Server.HtmlEncode(TextFile.FileName);
// Get the extension of the text.
string strExtension = Path.GetExtension(strFileName);
// Validate the file extension.
if (strExtension != ".TXT" && strExtension!=".txt")
{
Response.Write("<script>alert('Failed to import. Cause: Invalid text file.');</script>");
return;
}
// Generate the file name to save the text file.
//string strUploadFileName = "C:/Documents and Settings/rhlim/My Documents/Visual Studio 2005/WebSites/SoD/UploadFiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + strExtension;
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ';');
outputWriter.Write(fileContent);
TextFile.SaveAs(strExcelOutputFilename);
inputReader.Close();
}
//string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss")+xlExtension;
// Save the Excel spreadsheet on server.
//TextFile.SaveAs (strExcelOutputFilename);
}
else Response.Write("<script>alert('Failed to import. Cause: No file found');</script>");
}
}
Currently I am having some file saving errors
Any suggestions? Thanks a lot!

That's because Excel doesnt support pipelines you have to convert it so comma's or semicolumns like:
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ',');
outputWriter.Write(fileContent);
}

I googled and hope it will help you: http://csharp.net-informations.com/excel/csharp-create-excel.htm
Or, already answered: Create Excel (.XLS and .XLSX) file from C#
At the first link, the line xlWorkSheet.Cell[x,y] to put element in the dedicated cell.
FYI, xlsx format(new from Office 2007) will give you a great manipulation capability with code.

For generating and manipulating excel files, I personally prefer the NPOI library. Download it from Codeplex, add reference to the NPOI dlls to your project. Store a “template” excel file you would like in a known location, with the any column headers/formatting that you need. Then you just use npoi to make a copy of the template file and manipulate it at a sheet/row/column level and put whatever data you want.
The sample code snippet looks something like this. Assuming you have split your input into a List of strings
const string ExcelTemplateFile = "~/Resources/ExcelInputTemplate.xls";
const string ExcelWorksheetName = "Output Worksheet";
const int RequiredColumn = 1;
private HSSFWorkbook CreateExcelWorkbook(IEnumerable<String> inputData)
{
FileStream fs = new FileStream(Server.MapPath(ExcelTemplateFile), FileMode.Open, FileAccess.Read);
// Getting the complete workbook...
HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);
// Getting the worksheet by its name...
HSSFSheet sheet = templateWorkbook.GetSheet(ExcelWorksheetName);
int startRowIterator = 1;
foreach (string currentData in inputData)
{
sheet.CreateRow(startRowIterator).CreateCell(RequiredColumn).SetCellValue(currentData);
}
}

Related

Do C# NPOI support phonetic text (japanese/chinese text)?

I am converting excel file .xlsx with phonetic text (Japanese text) but the output file gives out warning that there are unreadable contents, and the data are missing from the file.
It seems that the issues were because NPOI can't process the phonetic guide from Microsoft Excel in Japanese language.
This only applies on .xlsx files and not .xls files.
I'm not sure how to attach the sample excel file but the image above shows what it looks like. Basically, if you use Microsoft Excel in Japanese version, there will be automatic phonetic guide for every kanji (Chinese character).
public void writeoutput(string val)
{
try
{
IWorkbook book;
string outPath = "<path for input file>";
using (FileStream file = new FileStream(outPath, FileMode.Open, FileAccess.Read))
{
try
{
book = new XSSFWorkbook(file);
}
catch (Exception e)
{
book = null;
}
if (book == null)
{
book = new HSSFWorkbook(file);
}
file.Close();
}
//ISheet sheet = outputSheet.GetSheet("Sheet1");
ISheet sheet = book.GetSheetAt(0);
sheet.CopySheet("NewSheet", false);
IRow dataRow = sheet.GetRow(35) ?? sheet.CreateRow(35);
ICell cell = dataRow.GetCell(8) ?? dataRow.CreateCell(8);
cell.SetCellValue(val);
//File.Delete(outPath);
outPath = "<path for output file>";
using (FileStream file = new FileStream(outPath, FileMode.OpenOrCreate, FileAccess.Write))
{
book.Write(file);
file.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
textBox2.Text = "done";
}
}
I tried disable the phonetic guide in Microsoft Excel and the processing of the .xlsx file works with no issues but I can only disable the phonetic guide on the text one by one and it is very time consuming.

How do I append only updated texts?

I have a Winform control to write notes whose contents are periodically uploaded to the server.
I need to create a local file as a backup to save the contents of the notes.
When I type text into the notebox, the content remains in the note box and gets saved into the local text file. However, when I enter more texts to the note-box, the previous content as well as the new content gets appended to the local file.
How do I make sure that only the recent content gets appended to the local file? If i clear the note-box content, no content gets logged on to the server.
private void btnNote_Click(object sender, EventArgs e)
{
Note noteFrm = new Note();
//set Note Text
noteFrm.NoteText = _timeCard.NoteText;
if (noteFrm.ShowDialog() == DialogResult.OK)
{
//Save notes locally as well
string path = #"C:\QB Notes\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string projname = this._timeCard.Project.ProjectName.TrimEnd()+".txt";
string fileloc = path + projname;
// FileStream fs = null;
if (!File.Exists(fileloc))
{
using (TextWriter txt = new StreamWriter(fileloc))
{
// TextWriter txt = new StreamWriter(fileloc);
txt.Write(noteFrm.NoteText + Environment.NewLine);
txt.Close();
}
}
else if (File.Exists(fileloc))
{
using (var txt = new StreamWriter(fileloc, true))
{
txt.BaseStream.Seek(0, SeekOrigin.End);
txt.Write(noteFrm.NoteText + Environment.NewLine);
txt.Close();
}
}
//noteFrm.NoteText="";
//get Note Text
_timeCard.NoteText = noteFrm.NoteText;
Utils.LogManager.write("New Note Text: " + noteFrm.NoteText);
}
}
If you want the file to always match what is in the text box, then I'd suggest that you replace your whole if (!File.Exists(fileloc)) block with just this:
File.WriteAllText(fileloc, noteFrm.NoteText + Environment.NewLine);
That will create the file if needed, open the file, replace all the contents with what is in the text box, and close the file.

Error message wile trying to open .xls file

I am creating an excel file on the fly for sending it an an attachment in an email. The relevant code snippet is provided below (It's a console app)
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
.............................................
.............................................
byte[] data = GetData(dt);
//save the data to a memory stream
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(ms, attachmentName, "application/vnd.ms-excel"));
....................................
....................................
//send email
smtpClient.Send(mailMsg); }
catch (Exception ex)
{
throw ex;
}
}
private static byte[] GetData(DataTable dt)
{
string strBody = DataTable2ExcelString(dt);
byte[] data = Encoding.ASCII.GetBytes(strBody);
return data;
}
private static string DataTable2ExcelString(System.Data.DataTable dt)
{
string excelSheetName = "Sheet1";
StringBuilder sbTop = new StringBuilder();
sbTop.Append("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" ");
sbTop.Append("xmlns=\" http://www.w3.org/TR/REC-html40\"><head><meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">");
sbTop.Append("<meta name=ProgId content=Excel.Sheet ><meta name=Generator content=\"Microsoft Excel 9\"><!--[if gte mso 9]>");
sbTop.Append("<xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>" + excelSheetName + "</x:Name><x:WorksheetOptions>");
sbTop.Append("<x:Selected/><x:ProtectContents>False</x:ProtectContents><x:ProtectObjects>False</x:ProtectObjects>");
sbTop.Append("<x:ProtectScenarios>False</x:ProtectScenarios></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets>");
sbTop.Append("<x:ProtectStructure>False</x:ProtectStructure><x:ProtectWindows>False</x:ProtectWindows></x:ExcelWorkbook></xml>");
sbTop.Append("<![endif]-->");
sbTop.Append("</head><body><table>");
string bottom = "</table></body></html>";
StringBuilder sbHeader = new StringBuilder();
//Header
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Columns[i].ColumnName + "</td>");
}
sbHeader.Append("</tr>");
//Items
for (int x = 0; x < dt.Rows.Count; x++)
{
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Rows[x][i] + "</td>");
}
sbHeader.Append("</tr>");
}
string data = sbTop.ToString() + sbHeader.ToString() + bottom;
return data;
}
This works but when I tried to open the excel file from the attachement, I receive:
I checked an found some solution in SO Post but could not make it to work. I tried like <x:DisplayAlerts>False</x:DisplayAlerts> but didn't work.
If the file you want to create and send doesn't have to be in exactly ".xls" format.. and if you are comfortable with ".xlsx" format... I think you might wanna try with EPPlus library, as it was mentioned Here. As I said you have to work with ".xlsx" (you can work with other excel formats but you'll get the same message about the file format when you open the file). So you can create the Excel file in temp folder with EPPlus using the DataTable as sorce and send the temp file by email... something like this for example:
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
string temp = Path.GetTempPath(); // Get %TEMP% path
string file = "fileNameHere.xlsx";
string path = Path.Combine(temp, file); // Get the whole path to the file
FileInfo fi = new FileInfo(path);
using (ExcelPackage pck = new ExcelPackage(fi))
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Table");
ws.Cells["A1"].LoadFromDataTable(dt, true);
pck.Save();
}
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(path, "application/vnd.ms-excel"));
try
{
//send email
smtp.Send(mailMsg);
}
catch (Exception)
{
//do smth..
}
finally
{
File.Delete(path);
}
}
catch (Exception ex)
{
throw ex;
}
}
I created a simple DataTable, sent it to myself in ".xlsx" format and was able to open it without any "Format warnings". I hope that helps.
The warning is display by MS Excel application because your file is not a real Excel file. It is an HTML with XLS extension. An XLS file is a binary file. MS Excel recognizes the HTML file and it display the file in its spreadsheet grid.
MS Excel displays security warnings for files that comes from external sources like email or internet.
The best solution is to use an Excel library that saves real Excel files in xls (old Excel file format) or xlsx (new Excel file format).
You can choose between free libraries like NPOI, EPPlus or commercial libraries like EasyXLS. Some of them saves only xls files, other only xlsx files and a few of them supports both file formats.
Solution to the warning / error “The file you are trying to open is in a different format than specified by the file extension”
Cause :
This happens because in the traditional Export to Excel method, the GridView is first converted to an HTML string and then that HTML string is exported to Excel. Thus originally it is not an Excel file hence the Excel Application throws the warning / error “The file you are trying to open is in a different format than specified by the file extension”.
Solution :
The solution to this problem is using ClosedXML library which is wrapper over the DocumentFormat.OpenXml library.
Dependency : OpenXml SDK 2.0 must be installed in system
You can get more help here :)

Print excel file to pdf in landscape mode using C#

I have a project that it should print check bill in both excel and pdf format.
Originally I use NPOI to print excel and Spire to print pdf using the excel file:
public HSSFWorkbook Workbook;
public void SaveExcelFile(string FilePath)
{
this.AutoSizeColumn();
FilePath = FilePath == "" ? AppDomain.CurrentDomain.BaseDirectory + "sample.xls" : FilePath;
var File = new FileStream(FilePath, FileMode.Create);
Workbook.Write(File);
File.Close();
}
public void SavePdfFileFromExcel(string ExcelFilePath, string PdfFilePath)
{
Workbook pdfWorkbook = new Workbook();
pdfWorkbook.LoadFromFile(ExcelFilePath);
pdfWorkbook.SaveToFile(PdfFilePath, Spire.Xls.FileFormat.PDF);
}
But Spire will just print the pdf in portrait, and the bill will look small and ugly. I want to know if there's a way I can print the pdf in landscape.
Or I should use iText to create a pdf format by self?
Try like this:
public void ExcelLandscapeFormat()
{
try
{
((Microsoft.Office.Interop.Excel._Worksheet)
excelWbook.ActiveSheet).PageSetup.Orientation =
Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape;
excelWbook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF,
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + output);
}
catch
{ }
}

Need to open and save Excel file before reading it

I have a method were I create an Excelsheet. When the file is created I need to open it and save it manually in Excel before I can read it with Excel Data Reader. If I open and save the exact same file without changeing anything I can read it like I wan't it to work. Does anyone know how I can:
a) Save it properly when creating the file (using EPPlus)?
or
b) Open the already created file and save it properly by using C# before I try to read it?
My create method:
public void CreateAnnuityExcelSheet(List<Calculation> cList, FormCollection form, int DTCyear)
{
string fileName = "test";
string path = #"C:\ExcelFiles\" + fileName + ".xlsx"; //Path for the file
FileInfo info = new FileInfo(path);
info.Directory.Create(); //If C:\ExcelFiles does not exist, create it
if (!info.Exists)
{
using (ExcelPackage package = new ExcelPackage(info))
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add(fileName);
//Filling the worksheet with values here...
package.SaveAs(info);
}
}
}
My read method:
[HttpPost]
public ActionResult ShowExcelFile(GetExcel model)
{
List<Calculation> cList = new List<Calculation>();
DataSet result = null;
var file = model.Files[0];
if (file != null && file.ContentLength > 0)
{
// .xlsx
IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(file.InputStream);
reader.IsFirstRowAsColumnNames = true;
result = reader.AsDataSet();
reader.Close();
var PV = Convert.ToDecimal(data.Table.Rows[1][6]); //Works fine if the file is opened and saved in Excel. Else null..
//Work with the dataset here. When the file is not opened and saved it gets null everywhere. Else it works fine
}
return View("ShowExcelFile", model);
}
I have also tried using WriteAllBytes instead of using package.SaveAs():
byte[] data = package.GetAsByteArray();
System.IO.File.WriteAllBytes(path, data);
This gets my the exact same result. I still need to open and save the file manually.

Categories