IQueryable<OFSOMEOBJECT> Export to excel - c#

Well, this certainly might have not been asked before.
I have a method that returns me an IQueryable, the client requirement is one specific example we should export that to excel without showing the results in a gridview.
Any idea?
string strSql = BuildQuery();
try
{
var list = RequestBaseBL.GetRequestByCustomQuery(strSql, DdlRequestType.SelectedValue).ToList();

to export in excel have a look here:
http://epplus.codeplex.com/releases/view/42439
then you can create your own class to generate excel export for IEnumerable
here some hint (these are part of more large object so only hints, nothing compiling surely) at the possible from one of my projects:
public interface IExcelReporting : IServiceObject
{
ColumnsExcel Columns { get; }
void SetDatasource(IEnumerable datasource);
void SetHeaderLabelMerge(int columnMerge);
void AddHeader(string label, string value);
Byte[] ExportToExcel(string title, string author, DateTime date);
}
an example of implementation :
public Byte[] ExportToExcel(string title, string author, DateTime date)
{
ExcelPackage package = new ExcelPackage();
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title);
if (_Columns != null)
{
Dictionary<int, Func<object, string>> internalMappingGetter = new Dictionary<int, Func<object, string>>();
//create the Header of the body
foreach (ColumnExcel entity in _Columns)
{
worksheet.Cells[RowIndex, ColumnIndex].Value = entity.HeaderName;
worksheet.Cells[RowIndex, ColumnIndex].Style.WrapText = true;
BorderCell(worksheet.Cells[RowIndex, ColumnIndex]);
worksheet.Column(ColumnIndex).Width = entity.Width;
ColumnIndex++;
}
RowIndex++;
if (_DataSource != null)
{
foreach (Object o in _DataSource)
{
ColumnIndex = 1;
foreach (ColumnExcel column in _Columns)
{
column.Apply(worksheet.Cells[RowIndex, ColumnIndex], o);
worksheet.Column(ColumnIndex).BestFit = true;
worksheet.Cells[RowIndex, ColumnIndex].Style.WrapText = true;
//BorderCell(worksheet.Cells[RowIndex, ColumnIndex]);
ColumnIndex++;
}
RowIndex++;
}
}
and the column class:
public class ColumnsExcel : IEnumerable
{
List<ColumnExcel> _Columns;
public ColumnsExcel()
{
_Columns = new List<ColumnExcel>();
}
public void AddInt(Func<object,int> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelInt(headerName, width, format, getValue);
_Columns.Add(entity);
}
public void AddString(Func<object, string> getValue, string headerName, int width )
{
ColumnExcel entity = new ColumnExcelstring(headerName, width, getValue);
_Columns.Add(entity);
}
public void AddDateTime(Func<object, DateTime?> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelDateTime(headerName, width, format, getValue);
_Columns.Add(entity);
}
public void AddDecimal(Func<object, decimal> getValue, string headerName, int width, string format)
{
ColumnExcel entity = new ColumnExcelDecimal(headerName, width, format, getValue);
_Columns.Add(entity);
}
public IEnumerator GetEnumerator()
{
return _Columns.GetEnumerator();
}
}
and its use :
//prepare the Ienumerable<MyObject>
var interventi = GetInterventoSchedeConsuntivi()
//prepare the report
IExcelReporting report = ReportingFactory.GetInstance();
report.SetDatasource(interventi);
report.AddHeader("Lotto:", lotto);
report.Columns.AddString((object v) => ((InterventoSchedeConsuntiviView)v).Lotto, "Lotto", 20);
using (System.IO.Stream s = File.Create(filepath))
{
byte[] csv = report.ExportToExcel(("titleFile", string.Empty, Servizi.DataOra.Now);
s.Write(csv, 0, csv.Length);
}

Related

Get absolute address of range

In old school Excel Interop, I can use the following code to generate an absolute address and use it inside a formula:
range.Formula = $"=sum({myRange.Address[false, true]})";
What is the EPPlus equivalent of this line, to get an absolute address (with an absolute row and/or column on demand)?
For an approach, that uses only EPPlus methods, there are static methods like ExcelCellBase.GetAddress (with a couple of overloads) that return absolute addresses:
public abstract class ExcelCellBase
{
public static string GetAddress(
int Row,
int Column,
bool Absolute
);
public static string GetAddress(
int Row,
bool AbsoluteRow,
int Column,
bool AbsoluteCol
);
public static string GetAddress(
int FromRow,
int FromColumn,
int ToRow,
int ToColumn,
bool FixedFromRow,
bool FixedFromColumn,
bool FixedToRow,
bool FixedToColumn
);
/* ... and others, see comments */
}
An extension method could be as easy as this one:
public static class EpPlusExtensions
{
public static string GetAddress(
this ExcelRangeBase range,
bool absoluteRow = false,
bool absoluteColumn = false)
{
return ExcelCellBase.GetAddress(
range.Start.Row,
range.Start.Column,
range.End.Row,
range.End.Column,
absoluteRow,
absoluteColumn,
absoluteRow,
absoluteColumn);
}
}
Well, there isn't a built in method, but you can do the following:
string GetAddress(ExcelRange rgn, bool absoluteRow, bool absoluteColumn,bool includeSheetName=false)
{
string address = rgn.Address;
if (absoluteColumn)
{
address = Regex.Replace(address, #"\b([A-Z])", #"$$$1");
}
if (absoluteRow)
{
address = Regex.Replace(address, #"([0-9]+)", #"$$$1");
}
if (includeSheetName)
{
address = $"'{rgn.Worksheet.Name}'!{address}";
}
return address;
}
Or as an extension method, so you can use like interop:
public static class EpplusExtensions
{
public static string Address(this ExcelRange rgn, bool absoluteRow, bool absoluteColumn, bool includeSheetName=false)
{
string address = rgn.Address;
if (absoluteColumn)
{
address = Regex.Replace(address, #"\b([A-Z])", #"$$$1");
}
if (absoluteRow)
{
address = Regex.Replace(address, #"([0-9]+)", #"$$$1");
}
if (includeSheetName)
{
address = $"'{rgn.Worksheet.Name}'!{address}";
}
return address;
}
}
Usage:
using (var ep = new ExcelPackage(new FileInfo(file)))
{
var sh = ep.Workbook.Worksheets.First();
ExcelRange myRange = sh.Cells[1, 1, 26, 36];
var absoluteColumn = myRange.Address(false, true);
var absoluteRow = myRange.Address(true, false);
var absolute = myRange.Address(true, true);
var relative = myRange.Address(false, false);
var withSheetName = myRange.Address(true, true, true);
}

Find a string and location in PDF file using iTextSharp using ASP.Net C#

I am trying to find a string and it's location in a PDF using iTextSharp in Asp.net C# for editing. But so far with the help available on Google I am unable to do it. This is the current code but it does read text chunk by chunk but couldn't find the required text. Need help Thanks
public class RectAndText
{
public iTextSharp.text.Rectangle Rect;
public String Text;
public RectAndText(iTextSharp.text.Rectangle rect, String text)
{
this.Rect = rect;
this.Text = text;
}
}
public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy
{
public List<RectAndText> myPoints = new List<RectAndText>();
public String TextToSearchFor { get; set; }
public System.Globalization.CompareOptions CompareOptions { get; set; }
public MyLocationTextExtractionStrategy(String textToSearchFor, System.Globalization.CompareOptions compareOptions = System.Globalization.CompareOptions.None)
{
this.TextToSearchFor = textToSearchFor;
this.CompareOptions = compareOptions;
}
public override void RenderText(TextRenderInfo renderInfo)
{
base.RenderText(renderInfo);
var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);
if (startPosition < 0)
{
return;
}
var chars = renderInfo.GetCharacterRenderInfos().Skip(startPosition).Take(this.TextToSearchFor.Length).ToList();
var firstChar = chars.First();
var lastChar = chars.Last();
var bottomLeft = firstChar.GetDescentLine().GetStartPoint();
var topRight = lastChar.GetAscentLine().GetEndPoint();
var rect = new iTextSharp.text.Rectangle(
bottomLeft[Vector.I1],
bottomLeft[Vector.I2],
topRight[Vector.I1],
topRight[Vector.I2]
);
this.myPoints.Add(new RectAndText(rect, this.TextToSearchFor));
}
}
Call function
string thisDir = System.Web.Hosting.HostingEnvironment.MapPath("~/");
var testFile = thisDir + "example.pdf";
var t = new MyLocationTextExtractionStrategy("searchstring"); //need to search this searchstring
using (var r = new PdfReader(testFile))
{
var ex = PdfTextExtractor.GetTextFromPage(r, 1, t);
}
foreach (var p in t.myPoints)
{
Console.WriteLine(string.Format("Found text {0} at {1}x{2}", p.Text, p.Rect.Left, p.Rect.Bottom));
}
This can easily be managed (in iText7) using RegexBasedLocationExtractionStrategy.
This class can be constructed using a regular expression and pushes out the locations of the text matching the expression. Even if you can not switch to iText7, you can still have a look at the source code and see how we implemented it.

Correct way to store encryption key for SqlCipher database

I have a Xamarin application and have managed to download my data from my server to my device. I have also got it set up so that it can take a SqlCipher Encryption key to encrypt the data.
My question is where is the correct location to store my key that I use to encrypt this data? Is it to you KeyStore / KeyChain? Which mono classes should I be looking to use?
Due to the popularity of this question I am going to post my implementation of this:
PCL interface
public interface IAuth
{
void CreateStore();
IEnumerable<string> FindAccountsForService(string serviceId);
void Save(string pin,string serviceId);
void Delete(string serviceId);
}
Android
public class IAuthImplementation : IAuth
{
Context context;
KeyStore ks;
KeyStore.PasswordProtection prot;
static readonly object fileLock = new object();
const string FileName = "MyProg.Accounts";
static readonly char[] Password = null;
public void CreateStore()
{
this.context = Android.App.Application.Context;
ks = KeyStore.GetInstance(KeyStore.DefaultType);
prot = new KeyStore.PasswordProtection(Password);
try
{
lock (fileLock)
{
using (var s = context.OpenFileInput(FileName))
{
ks.Load(s, Password);
}
}
}
catch (Java.IO.FileNotFoundException)
{
//ks.Load (null, Password);
LoadEmptyKeyStore(Password);
}
}
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var r = new List<string>();
var postfix = "-" + serviceId;
var aliases = ks.Aliases();
while (aliases.HasMoreElements)
{
var alias = aliases.NextElement().ToString();
if (alias.EndsWith(postfix))
{
var e = ks.GetEntry(alias, prot) as KeyStore.SecretKeyEntry;
if (e != null)
{
var bytes = e.SecretKey.GetEncoded();
var password = System.Text.Encoding.UTF8.GetString(bytes);
r.Add(password);
}
}
}
return r;
}
public void Delete(string serviceId)
{
var alias = MakeAlias(serviceId);
ks.DeleteEntry(alias);
Save();
}
public void Save(string pin, string serviceId)
{
var alias = MakeAlias(serviceId);
var secretKey = new SecretAccount(pin);
var entry = new KeyStore.SecretKeyEntry(secretKey);
ks.SetEntry(alias, entry, prot);
Save();
}
void Save()
{
lock (fileLock)
{
using (var s = context.OpenFileOutput(FileName, FileCreationMode.Private))
{
ks.Store(s, Password);
}
}
}
static string MakeAlias(string serviceId)
{
return "-" + serviceId;
}
class SecretAccount : Java.Lang.Object, ISecretKey
{
byte[] bytes;
public SecretAccount(string password)
{
bytes = System.Text.Encoding.UTF8.GetBytes(password);
}
public byte[] GetEncoded()
{
return bytes;
}
public string Algorithm
{
get
{
return "RAW";
}
}
public string Format
{
get
{
return "RAW";
}
}
}
static IntPtr id_load_Ljava_io_InputStream_arrayC;
void LoadEmptyKeyStore(char[] password)
{
if (id_load_Ljava_io_InputStream_arrayC == IntPtr.Zero)
{
id_load_Ljava_io_InputStream_arrayC = JNIEnv.GetMethodID(ks.Class.Handle, "load", "(Ljava/io/InputStream;[C)V");
}
IntPtr intPtr = IntPtr.Zero;
IntPtr intPtr2 = JNIEnv.NewArray(password);
JNIEnv.CallVoidMethod(ks.Handle, id_load_Ljava_io_InputStream_arrayC, new JValue[]
{
new JValue (intPtr),
new JValue (intPtr2)
});
JNIEnv.DeleteLocalRef(intPtr);
if (password != null)
{
JNIEnv.CopyArray(intPtr2, password);
JNIEnv.DeleteLocalRef(intPtr2);
}
}
Call Create Store in the main activity of Android app first. - This could possibly be improved and remove CreateStrore() from the interface by checking if ks == null in Save and Delete and calling the method if true
iOS
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var records = SecKeyChain.QueryAsRecord(query, 1000, out result);
return records != null ?
records.Select(GetAccountFromRecord).ToList() :
new List<string>();
}
public void Save(string pin, string serviceId)
{
var statusCode = SecStatusCode.Success;
var serializedAccount = pin;
var data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);
//
// Remove any existing record
//
var existing = FindAccount(serviceId);
if (existing != null)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
//
// Add this record
//
var record = new SecRecord(SecKind.GenericPassword);
record.Service = serviceId;
record.Generic = data;
record.Accessible = SecAccessible.WhenUnlocked;
statusCode = SecKeyChain.Add(record);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not save account to KeyChain: " + statusCode);
}
}
public void Delete(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
var statusCode = SecKeyChain.Remove(query);
if (statusCode != SecStatusCode.Success)
{
throw new Exception("Could not delete account from KeyChain: " + statusCode);
}
}
string GetAccountFromRecord(SecRecord r)
{
return NSString.FromData(r.Generic, NSStringEncoding.UTF8);
}
string FindAccount(string serviceId)
{
var query = new SecRecord(SecKind.GenericPassword);
query.Service = serviceId;
SecStatusCode result;
var record = SecKeyChain.QueryAsRecord(query, out result);
return record != null ? GetAccountFromRecord(record) : null;
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
WP
public class IAuthImplementation : IAuth
{
public IEnumerable<string> FindAccountsForService(string serviceId)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] auths = store.GetFileNames("MyProg");
foreach (string path in auths)
{
using (var stream = new BinaryReader(new IsolatedStorageFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, store)))
{
int length = stream.ReadInt32();
byte[] data = stream.ReadBytes(length);
byte[] unprot = ProtectedData.Unprotect(data, null);
yield return Encoding.UTF8.GetString(unprot, 0, unprot.Length);
}
}
}
}
public void Save(string pin, string serviceId)
{
byte[] data = Encoding.UTF8.GetBytes(pin);
byte[] prot = ProtectedData.Protect(data, null);
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, store))
{
stream.WriteAsync(BitConverter.GetBytes(prot.Length), 0, sizeof(int)).Wait();
stream.WriteAsync(prot, 0, prot.Length).Wait();
}
}
public void Delete(string serviceId)
{
var path = GetAccountPath(serviceId);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
store.DeleteFile(path);
}
}
private string GetAccountPath(string serviceId)
{
return String.Format("{0}", serviceId);
}
public void CreateStore()
{
throw new NotImplementedException();
}
}
This is an adaptation of the Xamarin.Auth library (Found Here) but removes the dependency from the Xamarin.Auth library to provide cross platform use through the interface in the PCL. For this reason I have simplified it to only save one string. This is probably not the best implementation but it works in my case. Feel free to expand upon this
There is a nuget package called KeyChain.NET that encapsulated this logic for iOs, Android and Windows Phone.
It's open source and you have find sample at its github repository
More info at this blog post

How to convert Telerik ORM entity list to csv file

Is there easier way to convert telerik orm entity list to csv format?
The following simple static class will help you in this task. Note that it will create a .csv file, which contains the values of the entity's properties without taking into account the navigation properties:
public static partial class EntitiesExporter
{
public static void ExportEntityList<T>(string fileLocation, IEnumerable<T> entityList, string seperator = " , ")
{
string content = CreateFileContent<T>(entityList, seperator);
SaveContentToFile(fileLocation, content);
}
private static string CreateFileContent<T>(IEnumerable<T> entityList, string seperator)
{
StringBuilder result = new StringBuilder();
List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (PropertyInfo item in typeof(T).GetProperties())
{
if (item.CanWrite)
{
properties.Add(item);
}
}
foreach (T row in entityList)
{
var values = properties.Select(p => p.GetValue(row, null));
var line = string.Join(seperator, values);
result.AppendLine(line);
}
return result.ToString();
}
private static void SaveContentToFile(string fileLocation, string content)
{
using (StreamWriter writer = File.CreateText(fileLocation))
{
writer.Write(content);
writer.Close();
}
}
}
You can consume the class like this in your code:
using (EntitiesModel dbContext = new EntitiesModel())
{
IQueryable<Category> cats = dbContext.Categories;
string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string fileLocation = Path.Combine(appDir, "test.csv");
EntitiesExporter.ExportEntityList<Category>(fileLocation, cats);
}
I hope this helps.

How to sort an arraylist on date?

Code:
while ((linevalue = filereader.ReadLine()) != null)
{
items.Add(linevalue);
}
filereader.Close();
items.Sort();
//To display the content of array (sorted)
IEnumerator myEnumerator = items.GetEnumerator();
while (myEnumerator.MoveNext())
{
Console.WriteLine(myEnumerator.Current);
}
The program above displays all the values. How to extract only the dates and sort it in ascending order?
I am not let to work with linq, use the exception or threading or any other stuff. I have to stick with the File Stream, try to get my data out of the text file, sort and store it, so that i can retrieve it, view it and edit it and search for any particular date and see the date of joining records for that date. Can't figure out. Struggling
Basically, don't try and work with the file as lines of text; separate that away, so that you have one piece of code which parses that text into typed records, and then process those upstream when you only need to deal with typed data.
For example (and here I'm assuming that the file is tab-delimited, but you could change it to be column indexed instead easily enough); look at how little work my Main method needs to do to work with the data:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
static class Program
{
static void Main()
{
foreach (var item in ReadFile("my.txt").OrderBy(x => x.Joined))
{
Console.WriteLine(item.Names);
}
}
static readonly char[] tab = { '\t' };
class Foo
{
public string Names { get; set; }
public int Age { get; set; }
public string Designation { get; set; }
public DateTime Joined { get; set; }
}
static IEnumerable<Foo> ReadFile(string path)
{
using (var reader = File.OpenText(path))
{
// skip the first line (headers), or exit
if (reader.ReadLine() == null) yield break;
// read each line
string line;
var culture = CultureInfo.InvariantCulture;
while ((line = reader.ReadLine()) != null)
{
var parts = line.Split(tab);
yield return new Foo
{
Names = parts[0],
Age = int.Parse(parts[1], culture),
Designation = parts[2],
Joined = DateTime.Parse(parts[3], culture)
};
}
}
}
}
And here's a version (not quite as elegant, but working) that works on .NET 2.0 (and probably on .NET 1.1) using only ISO-1 language features; personally I think it would be silly to use .NET 1.1, and if you are using .NET 2.0, then List<T> would be vastly preferable to ArrayList. But this is "worst case":
using System;
using System.Collections;
using System.Globalization;
using System.IO;
class Program
{
static void Main()
{
ArrayList items = ReadFile("my.txt");
items.Sort(FooByDateComparer.Default);
foreach (Foo item in items)
{
Console.WriteLine(item.Names);
}
}
class FooByDateComparer : IComparer
{
public static readonly FooByDateComparer Default
= new FooByDateComparer();
private FooByDateComparer() { }
public int Compare(object x, object y)
{
return ((Foo)x).Joined.CompareTo(((Foo)y).Joined);
}
}
static readonly char[] tab = { '\t' };
class Foo
{
private string names, designation;
private int age;
private DateTime joined;
public string Names { get { return names; } set { names = value; } }
public int Age { get { return age; } set { age = value; } }
public string Designation { get { return designation; } set { designation = value; } }
public DateTime Joined { get { return joined; } set { joined = value; } }
}
static ArrayList ReadFile(string path)
{
ArrayList items = new ArrayList();
using (StreamReader reader = File.OpenText(path))
{
// skip the first line (headers), or exit
if (reader.ReadLine() == null) return items;
// read each line
string line;
CultureInfo culture = CultureInfo.InvariantCulture;
while ((line = reader.ReadLine()) != null)
{
string[] parts = line.Split(tab);
Foo foo = new Foo();
foo.Names = parts[0];
foo.Age = int.Parse(parts[1], culture);
foo.Designation = parts[2];
foo.Joined = DateTime.Parse(parts[3], culture);
items.Add(foo);
}
}
return items;
}
}
I'm not sure why you'd want to retrieve just the dates. You'd probably be better reading your data into Tuples first. Something like
List<Tuple<string, int, string, DateTime>> items.
Then you can sort them by items.Item4, which will be the date.
You can use LINQ and split the line according to tabs to only retrieve the date and order them through a conversion to date.
while ((linevalue = filereader.ReadLine()) != null)
{
items.Add(linevalue.Split('\t').Last());
}
filereader.Close();
items.OrderBy(i => DateTime.Parse(i));
foreach(var item in items)
{
Console.WriteLine(item);
}
get the desired values in Array from the file...
public class DateComparer : IComparer {
public int Compare(DateTime x, DateTime y) {
if(x.Date > y.Date)
return 1;
if(x.Date < y.Date)
return -1;
else
return 0;
}
}
list.Sort(new DateComparer());

Categories