I have developed a program to get the Linq query and write it to excel file using EPPLUS (the below code) but it is slow because it is filling the file line by line. is there anyway to fill the excel file all at once? to export all the query at once to excel file?
fnctnData is the query result
Thanks for the help
public Boolean GenerateExcel(IEnumerable<ReportData> fnctnData,string fileName,ReportFilTer smf)
{
Boolean ret=false;
try
{
string temp = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
DirectoryInfo di = new DirectoryInfo(temp);
string templateFile = Path.Combine(di.Parent.FullName, #"templates\Report.xlsx");
FileInfo itemplateFile = new FileInfo(templateFile);
FileInfo ReportFile = new FileInfo(fileName);
using (ExcelPackage package = new ExcelPackage(ReportFile,itemplateFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.First();
int i = 5;
foreach (var item in fnctnData)
{
worksheet.Cells["A" + i].Value = item.a;
worksheet.Cells["B" + i].Value = item.c;
worksheet.Cells["C" + i].Value = item.d;
worksheet.Cells["D" + i].Value = string.Format("{0:dd/MM/yyyy hh:mm:ss}", item.Date);
worksheet.Cells["E" + i].Value = item.e;
worksheet.Cells["F" + i].Value = item.f;
worksheet.Cells["G" + i].Value = item.g;
i++;
}
package.SaveAs(ReportFile);
ret = true;
}
}
catch (Exception ex)
{
LibraryLogger.LoggerSoftwareUtility.Error(string.Format("GenerateExcel Exception : {0}", ex));
throw ex;
}
return ret;
}
Related
I have an excel file that has around 40 to 50 sheets of size 8mb and will be increasing may be 15 to 20mb and many are inter-linked with multiple formulas.
So basically if one cell values changes then it will affect multiple sheets because of function and vlookup's etc.
Now I am trying to manipulate the excel sheet dynamically using c#. But I see that the are not calculating instantly.
I tried using ExcelLibrary's Calculate function to do this.
Problems with ExcelLibrary are:
a. It is very very slow with Calculate, ExcelPackage(Open) and Save functions**(Makes it unusable)**.
b. Need to know all the dependent cell to trigger calculate on them(not preferring workbook or worksheet calculate(the debugger never comes to next line)) which is not efficient way to manage code in feature.
I believe the problem is because it works with ooxml and actually not directly with excel(not sure we can work with excel directly so that it will be like inserting data manually using code).
Note: Trying to test with Excel interop(hoping it will do the job because it opens excel file in background while manipulating.)
private void TestExcelWithSimultaneousReadOfTwoSheetsFromFile(string fileName)
{
try
{
int count = 0;
int rowIndex = 1702;
for (int rowCount = 0; rowCount < 3; rowCount++)
{
count = ReadCountFromProdReport(fileName);
WriteRowToProd(fileName, rowIndex + rowCount);
count = ReadCountFromProdReport(fileName);
}
}
catch (Exception ex)
{
throw ex;
}
}
private void WriteRowToProd(string fileName, int rowIndex)
{
try
{
string logDirectory = System.Configuration.ConfigurationManager.AppSettings["LogDirectory"].ToString().Trim();
string filePath = logDirectory + fileName + ConfigurationManager.AppSettings["ExcelSaveFileExtension"].ToString().Trim();
using (ExcelPackage excelPackage = new ExcelPackage(new FileInfo(filePath)))
{
foreach (ExcelWorksheet workSheet in excelPackage.Workbook.Worksheets)
{
if (workSheet.Name.Trim() == "Sample")
{
workSheet.Cells["C" + rowIndex].Value = "15.05.2017";
workSheet.Cells["D" + rowIndex].Value = 21701503;
workSheet.Cells["E" + rowIndex].Value = "21701503109W";
workSheet.Cells["F" + rowIndex].Value = 304;
workSheet.Cells["G" + rowIndex].Value = 200;
workSheet.Cells["H" + rowIndex].Value = 1520;
workSheet.Cells["I" + rowIndex].Value = 11350;
workSheet.Cells["J" + rowIndex].Formula = "=7.85*G1701*H1701*I1701/1000000000";
workSheet.Cells["K" + rowIndex].Value = 27.080;
excelPackage.Save();
break;
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
private int ReadCountFromProdReport(string fileName)
{
try
{
string logDirectory = System.Configuration.ConfigurationManager.AppSettings["LogDirectory"].ToString().Trim();
string filePath = logDirectory + fileName + ConfigurationManager.AppSettings["ExcelSaveFileExtension"].ToString().Trim();
using (ExcelPackage excelPackage = new ExcelPackage(new FileInfo(filePath)))
{
object count = null;
foreach (ExcelWorksheet workSheet in excelPackage.Workbook.Worksheets)
{
if (workSheet.Name.Trim() == "Report")
{
count = workSheet.Cells["E23"].Value;
break;
}
}
return Convert.ToInt32(count);
}
}
catch (Exception ex)
{
throw ex;
}
}
I am trying to export an excel and make it password protected.
My code is given below.
But i am getting error:
Excel completed file level validation and repair.
Some parts of this workbook may have been repaired or discarded.
I DON'T KNOW WHAT I AM DOING WRONG .
In-case i do it without the save As line for package then this error doesn't appear.
In my controller:
[HttpGet]
public FileStreamResult ExportToExcel()
{
_objService = new ServiceBAL();
List<ReconcilationEntity> Objmodel = new List<ReconcilationEntity>();
Objmodel = _objService.GetCreditsudharLeads();
String URL = string.Empty;
if (!Directory.Exists(Server.MapPath("~/TempExcel")))
{
System.IO.Directory.CreateDirectory(Server.MapPath("~/TempExcel"));
}
String Filepath = Server.MapPath("~/TempExcel");
string date = DateTime.Now.ToShortDateString().Replace("/", "_") + "_" + DateTime.Now.ToShortTimeString().Replace(" ", "_").Replace(":", "_").Trim();
String FileName = "Creditsudhar_" + date + ".xlsx";
Filepath = Filepath + "\\" + FileName;
string[] columns = { "AffName", "AffPhone", "AffEmail", "ProductName", "ContactName", "Status", "CreatedOn", "Commission", "IsCommissionPaid", "Accountname", "AccountNumber", "BankName", "BankBranch", "IFSCCode", "PanNumber" };
var file = ExcelExportHelper.ExportExcel(ExcelExportHelper.ListToDataTable(Objmodel), Filepath, "Creditsudhar Reconcillation Sheet " + DateTime.Now.ToShortDateString(), true, columns);
var memStream = new MemoryStream(file);
return this.File(memStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName);
}
public static string ExcelContentType
{
get
{ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; }
}
public static DataTable ListToDataTable<T>(List<T> data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable dataTable = new DataTable();
for (int i = 0; i < properties.Count; i++)
{
PropertyDescriptor property = properties[i];
dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
}
object[] values = new object[properties.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = properties[i].GetValue(item);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
public static byte[] ExportExcel(DataTable dataTable, String Filepath, string heading = "", bool showSrNo = false, params string[] columnsToTake)
{
string fullPath = string.Empty;
byte[] ret;
DeleteUploadedFile(Filepath);
String result = String.Empty;
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(String.Format("{0} Data", heading));
int startRowFrom = String.IsNullOrEmpty(heading) ? 1 : 3;
if (showSrNo)
{
DataColumn dataColumn = dataTable.Columns.Add("#", typeof(int));
dataColumn.SetOrdinal(0);
int index = 1;
foreach (DataRow item in dataTable.Rows)
{
item[0] = index;
index++;
}
}
// add the content into the Excel file
workSheet.Cells["A" + startRowFrom].LoadFromDataTable(dataTable, true);
// autofit width of cells with small content
int columnIndex = 1;
foreach (DataColumn column in dataTable.Columns)
{
try
{
ExcelRange columnCells = workSheet.Cells[workSheet.Dimension.Start.Row, columnIndex, workSheet.Dimension.End.Row, columnIndex];
int maxLength = columnCells.Max(cell => cell.Value.ToString().Count());
if (maxLength < 150)
{
workSheet.Column(columnIndex).AutoFit();
}
columnIndex++;
}
catch (Exception ex)
{
if (!(ex is System.Threading.ThreadAbortException))
{
//Log other errors here
}
}
}
// format header - bold, yellow on black
using (ExcelRange r = workSheet.Cells[startRowFrom, 1, startRowFrom, dataTable.Columns.Count])
{
r.Style.Font.Color.SetColor(System.Drawing.Color.White);
r.Style.Font.Bold = true;
r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
r.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#1fb5ad"));
}
// format cells - add borders
using (ExcelRange r = workSheet.Cells[startRowFrom + 1, 1, startRowFrom + dataTable.Rows.Count, dataTable.Columns.Count])
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin;
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin;
r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
// removed ignored columns
for (int i = dataTable.Columns.Count - 1; i >= 0; i--)
{
if (i == 0 && showSrNo)
{
continue;
}
if (!columnsToTake.Contains(dataTable.Columns[i].ColumnName))
{
workSheet.DeleteColumn(i + 1);
}
}
if (!String.IsNullOrEmpty(heading))
{
workSheet.Cells["A1"].Value = heading;
workSheet.Cells["A1"].Style.Font.Size = 20;
workSheet.InsertColumn(1, 1);
workSheet.InsertRow(1, 1);
workSheet.Column(1).Width = 5;
}
System.IO.FileInfo fileinfo2 = new System.IO.FileInfo(Filepath);
DeleteUploadedFile(Filepath);
workSheet.Protection.SetPassword("myPassword");
workSheet.Protection.IsProtected = true;
workSheet.Protection.AllowSelectUnlockedCells = false;
workSheet.Protection.AllowSelectLockedCells = false;
package.SaveAs(fileinfo2, "myPassword");
ret = package.GetAsByteArray();
return ret;
}
}
public static void DeleteUploadedFile(String filePath)
{
try
{
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
catch (Exception ex)
{ }
}
public static byte[] ExportExcel<T>(List<T> data, String Filepath, string Heading = "", bool showSlno = false, params string[] ColumnsToTake)
{
return ExportExcel(ListToDataTable<T>(data), Filepath, Heading, showSlno, ColumnsToTake);
}
An answer mentioned SaveAs close the package, so the correct steps will be returning the saved file as array instead of using GetAsByteArray afterwards. Or simply use GetAsByteArray(passwords) without SaveAs.
I am trying to get some data from one datatable (facilData) and data from another datatable (ownerData) and write it to another datatable (dataStore). The second is not identical to the first. When I attempted my code below, I get the following error: "Unable to case object of type System.DBnull to System.String". Then the debugger takes me back and highlights (int)table2["rowIndex"] in the code below.
public void Write2Sheet(DataTable dt1, DataTable dt2, DataTable dt3, String newFilePath)
{
try
{
//Merge the three Datatables into the single Datatable source
var mdata = from table1 in facilData.AsEnumerable()
join table2 in ownerData.AsEnumerable() on (int)table1["rowIndex"] equals (int)table2["rowIndex"]
select new
{
rowIndex = (int)table1["rowIndex"],
Prog = (string)table1["Prog"],
cStatus = (string)table1["cStatus"],
bStatus = (string)table1["bStatus"],
fID = (string)table1["fID"],
fNam = (string)table1["fNam"],
fAdd = (string)table1["fAdd"],
fCity = (string)table1["fCity"],
fState = (string)table1["fState"],
fCode = (string)table1["fCode"],
oInfo = (string)table2["oInfo"],
pgRecId = (string)table1["pgRecId"],
lAct = (string)table1["lAct"]
};
foreach (var rec in mdata)
{
var row = dataStore.NewRow();
row["rowIndex"] = rec.rowIndex;
row["Prog"] = rec.Prog;
row["cStatus"] = rec.cStatus;
row["bStatus"] = rec.bStatus;
row["fID"] = rec.fID;
row["fNam"] = rec.fNam;
row["fAdd"] = rec.fAdd;
row["fCity"] = rec.fCity;
row["fState"] = rec.fState;
row["fCode"] = rec.fCode;
row["oInfo"] = rec.oInfo;
row["pgRecId"] = rec.pgRecId;
row["lAct"] = rec.lAct;
dataStore.Rows.Add(row);
}
}
catch (Exception e)
{
Write2LogFile("The data tables couldn't merge because: " + e.Message);
}
//Write from the Datatable source to the new spreadsheet and save it
try
{
FileInfo newSheet = new FileInfo(fileName);
using (ExcelPackage xPkg = new ExcelPackage(newSheet))
{
ExcelWorksheet worksheet = xPkg.Workbook.Worksheets[1];
var cell = worksheet.Cells;
int rI = 2;
foreach (DataRow dr in dataStore.Rows)
{
string iDX = rI.ToString();
worksheet.Cells["A" + iDX].Value = dr["Prog"].ToString();
worksheet.Cells["B" + iDX].Value = dr["cStatus"].ToString();
worksheet.Cells["C" + iDX].Value = dr["bStatus"].ToString();
worksheet.Cells["D" + iDX].Value = dr["fID"].ToString();
worksheet.Cells["E" + iDX].Value = dr["fNam"].ToString();
worksheet.Cells["F" + iDX].Value = dr["fAdd"].ToString();
worksheet.Cells["G" + iDX].Value = dr["fCity"].ToString();
worksheet.Cells["H" + iDX].Value = dr["fState"].ToString();
worksheet.Cells["I" + iDX].Value = dr["fCode"].ToString();
worksheet.Cells["J" + iDX].Value = dr["oInfo"].ToString();
worksheet.Cells["K" + iDX].Value = dr["pgRecId"].ToString();
worksheet.Cells["L" + iDX].Value = dr["lAct"].ToString();
rI++;
}
xPkg.Save();
}
}
catch (Exception ex)
{
Write2LogFile("Data was not written to spreadsheet because: " + ex.Message);
}
}
So, I figured it out. Instead of trying to do the query syntax, I went with the method syntax. I added an additional class as a container for my objects I wanted to add to the single datatable. Although none of the row-indices were null, I added a null check anyway. Here is my updated code:
public void Write2Sheet(DataTable dt1, DataTable dt2, DataTable dt3, String newFilePath)
{
try
{
//Merge the three Datatables into the single Datatable source
//method syntax
var mdata = facilData.AsEnumerable().Where(f => f[0] != typeof(DBNull)).Join(ownerData.AsEnumerable(),
table1 => table1.Field<int>(0),
table2 => table2.Field<int>(0),
(table1, table2) => new Class1 //container class
{
rowIndex = (int)table1[0],
Prog = table1[1].ToString(),
cStatus = table1[2].ToString(),
bStatus = table1[3].ToString(),
fID = table1[4].ToString(),
fNam = table1[5].ToString(),
fAdd = table1[6].ToString(),
fCity = table1[7].ToString(),
fState = table1[8].ToString(),
fCode = table1[9].ToString(),
oInfo = table2[1].ToString(),
pgRecId = table1[10].ToString(),
lAct = table1[11].ToString()
});
foreach (var rec in mdata)
{
var row = dataStore.NewRow();
row["rowIndex"] = rec.rowIndex;
row["Prog"] = rec.Prog;
row["cStatus"] = rec.cStatus;
row["bStatus"] = rec.bStatus;
row["fID"] = rec.fID;
row["fNam"] = rec.fNam;
row["fAdd"] = rec.fAdd;
row["fCity"] = rec.fCity;
row["fState"] = rec.fState;
row["fCode"] = rec.fCode;
row["oInfo"] = rec.oInfo;
row["pgRecId"] = rec.pgRecId;
row["lAct"] = rec.lAct;
dataStore.Rows.Add(row);
}
}
catch (Exception e)
{
Write2LogFile("The data tables couldn't merge because: " + e.Message);
}
//Write from the Datatable source to the new spreadsheet and save it
try
{
FileInfo newSheet = new FileInfo(fileName);
using (ExcelPackage xPkg = new ExcelPackage(newSheet))
{
ExcelWorksheet worksheet = xPkg.Workbook.Worksheets[1];
var cell = worksheet.Cells;
int rI = 2;
foreach (DataRow dr in dataStore.Rows)
{
string iDX = rI.ToString();
worksheet.Cells["A" + iDX].Value = dr["Prog"].ToString();
worksheet.Cells["B" + iDX].Value = dr["cStatus"].ToString();
worksheet.Cells["C" + iDX].Value = dr["bStatus"].ToString();
worksheet.Cells["D" + iDX].Value = dr["fID"].ToString();
worksheet.Cells["E" + iDX].Value = dr["fNam"].ToString();
worksheet.Cells["F" + iDX].Value = dr["fAdd"].ToString();
worksheet.Cells["G" + iDX].Value = dr["fCity"].ToString();
worksheet.Cells["H" + iDX].Value = dr["fState"].ToString();
worksheet.Cells["I" + iDX].Value = dr["fCode"].ToString();
worksheet.Cells["J" + iDX].Value = dr["oInfo"].ToString();
worksheet.Cells["K" + iDX].Value = dr["pgRecId"].ToString();
worksheet.Cells["L" + iDX].Value = dr["lAct"].ToString();
rI++;
}
xPkg.Save();
MessageBox.Show("Data was successfully added to the current spreadsheet.");
}
}
catch (Exception ex)
{
Write2LogFile("Data was not written to spreadsheet because: " + ex.Message);
}
}
I have a page where I want to upload a CSV file from my computer to database on the server and I have my opentext that looks like the following
using (StreamReader sr = File.OpenText(#"c:\users\workstationUsername\FileName.csv"))
This works fine on my local machine but when I push this to the server it tries to read the server's C Drive and I want it to read the physical file location that is sitting on the desktop of the user's computer not the server, when they click browse and upload..
Thank you
below is the complete code:
if (IsPostBack)
{
// SetDefaultDates();
Boolean fileOK = false;
String dateString = DateTime.Now.ToString("MMddyyyy");
String UserName = User.Identity.Name;
String path = Server.MapPath("~/Uploads/CSVs/");
string stringpath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
String fileName = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName);
stringpath = stringpath + fileName;
String LocationToSave = path + "\\" + fileName;
if (FileUpload1.HasFile)
{
String fileExtension =
System.IO.Path.GetExtension(FileUpload1.FileName).ToLower();
String[] allowedExtensions = { ".csv" };
for (int i = 0; i < allowedExtensions.Length; i++)
{
if (fileExtension == allowedExtensions[i])
{
fileOK = true;
}
}
}
if (fileOK)
{
try
{
//FileUpload1.PostedFile.SaveAs(LocationToSave + dateString + "-" + FileUpload1.FileName);
FileUpload1.PostedFile.SaveAs(LocationToSave);
Label1.Text = "File " + FileUpload1.FileName + " uploaded!";
DataTable dt = new DataTable();
string line = null;
int i = 0;
using (StreamReader sr = File.OpenText(stringpath))
{
while ((line = sr.ReadLine()) != null)
{
string[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
foreach (var item in data)
{
dt.Columns.Add(new DataColumn());
}
i++;
}
DataRow row = dt.NewRow();
row.ItemArray = data;
dt.Rows.Add(row);
}
}
}
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
copy.WriteToServer(dt);
}
}
}
catch (Exception ex)
{
Label1.Text = "File " + FileUpload1.FileName + " could not be uploaded." + ex.Message;
}
}
else
{
Label1.Text = "Cannot accept files of this type. " + FileUpload1.FileName;
}
}
SetDefaultDates();
}
If you have a FileUpload control, then instead of using (StreamReader sr = File.OpenText(#"c:\users\workstationUsername\FileName.csv")) which obvously is pointing to the server's hard drive you can do this:
(StreamReader sr = new StreamReader(fileUploadControl.FileContent))
//Do your stuff
You can't access the client's hard drive. That's a major security concern. You'll need to upload the file to your server, and read it from there.
It doesnt make sense to have a static read to the local machine, rather get user to upload it then update the database, this code is very limiting and has a high security risk. Rather create a steamreader object get the user to upload it then use the steam reader to process the csv.
I'm trying to read some files with ReadLine, but my file have some break lines that I need to catch (not all of them), and I don't know how to get them in the same array, neither in any other array with these separators... because... ReadLine reads lines, and break these lines, huh?
I can't replace these because I need to check it after the process, so I need to get the breaklines AND the content after that. That's the problem. How can I do that?
Here's my code:
public class ReadFile
{
string extension;
string filename;
System.IO.StreamReader sr;
public ReadFile(string arquivo, System.IO.StreamReader sr)
{
string ext = Path.GetExtension(arquivo);
sr = new StreamReader(arquivo, System.Text.Encoding.Default);
this.sr = sr;
this.extension = ext;
this.filename = Path.GetFileNameWithoutExtension(arquivo);
if (ext.Equals(".EXP", StringComparison.OrdinalIgnoreCase))
{
ReadEXP(arquivo);
}
else MessageBox.Show("Extensão de arquivo não suportada: "+ext);
}
public void ReadEXP(string arquivo)
{
string line = sr.ReadLine();
string[] words;
string[] Separators = new string[] { "<Segment>", "</Segment>", "<Source>", "</Source>", "<Target>", "</Target>" };
string ID = null;
string Source = null;
string Target = null;
DataBase db = new DataBase();
//db.CreateTable_EXP(filename);
db.CreateTable_EXP();
while ((line = sr.ReadLine()) != null)
{
try
{
if (line.Contains("<Segment>"))
{
ID = "";
words = line.Split(Separators, StringSplitOptions.None);
ID = words[0];
for (int i = 1; i < words.Length; i++ )
ID += words[i];
MessageBox.Show("Segment[" + words.Length + "]: " + ID);
}
if (line.Contains("<Source>"))
{
Source = "";
words = line.Split(Separators, StringSplitOptions.None);
Source = words[0];
for (int i = 1; i < words.Length; i++)
Source += words[i];
MessageBox.Show("Source[" + words.Length + "]: " + Source);
}
if (line.Contains("<Target>"))
{
Target = "";
words = line.Split(Separators, StringSplitOptions.None);
Target = words[0];
for (int i = 1; i < words.Length; i++)
Target += words[i];
MessageBox.Show("Target[" + words.Length + "]: " + Target);
db.PopulateTable_EXP(ID, Source, Target);
MessageBox.Show("ID: " + ID + "\nSource: " + Source + "\nTarget: " + Target);
}
}
catch (IndexOutOfRangeException e)
{
MessageBox.Show(e.Message.ToString());
MessageBox.Show("ID: " + ID + "\nSource: " + Source + "\nTarget: " + Target);
}
}
return;
}
If you are trying to read XML, try using the built in libaries, here is a simple example of loading a section of XML with <TopLevelTag> in it.
var xmlData = XDocument.Load(#"C:\folder\file.xml").Element("TopLevelTag");
if (xmlData == null) throw new Exception("Failed To Load XML");
Here is a tidy way to get content without it throwing an exception if missing from the XML.
var xmlBit = (string)xmlData.Element("SomeSubTag") ?? "";
If you really have to roll your own, then look at examples for CSV parsers,
where ReadBlock can be used to get the raw data including line breaks.
private char[] chunkBuffer = new char[4096];
var fileStream = new System.IO.StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
var chunkLength = fileStream.ReadBlock(chunkBuffer, 0, chunkBuffer.Length);