Im currently using Interop library in order to export excel templates to user but the client requested to change to openxml because it doesn't required excel to be installed on the server
using interop im able to add drop down list using interop in dedicated cell as following
worksheet.get_Range("A9", "A9").Value = "Region";
var Regions = _iFunctionalRepository.GetRegions(GetCurrentNeutralCultureId(), -1);
var RegionsArray = Regions.Select(x => x.Value + "- " + x.Text).ToArray();
var RegionsList = string.Join(",", RegionsArray);
//sectors ddl
worksheet.get_Range("B9", "B9").Validation.Delete();
worksheet.get_Range("B9", "B9").Validation.Add(
Microsoft.Office.Interop.Excel.XlDVType.xlValidateList,
Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertInformation,
Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween,
RegionsList,
Type.Missing);
worksheet.get_Range("B9", "B9").Validation.IgnoreBlank = true;
worksheet.get_Range("B9", "B9").Validation.InCellDropdown = true;
worksheet.get_Range("B9", "B9").Value = "---";
my code to export using open xml which need to add drop down list in cell B9 as example
using (ClosedXML.Excel.XLWorkbook wb = new ClosedXML.Excel.XLWorkbook())
{
var worksheet = wb.Worksheets.Add("GeneralInformation");
var worksheetHiddenSheet = wb.Worksheets.Add("generalHidden");
worksheet.Range("A1", "A1").Value = "title";
worksheet.Range("A1", "A1").Style.Font.SetFontSize(12);
worksheet.Range("A1", "A1").Style.Font.FontColor = ClosedXML.Excel.XLColor.White;
worksheet.Range("A2", "A1").Style.Fill.BackgroundColor = ClosedXML.Excel.XLColor.DodgerBlue;
worksheet.Range("A1", "A1").Style.Font.SetBold();
worksheet.Range("A1", "B1").Merge();
worksheet.Range("A9", "A9").Value = "regions";
var Regions = _iFunctionalRepository.GetRegions(GetCurrentNeutralCultureId(), -1);
var RegionsArray = Regions.Select(x => x.Value + "- " + x.Text).ToArray();
var RegionsList = string.Join(",", RegionsArray);
//drop down code
string randomFileName = "Project Template " + DateTime.Now.ToString("dd-MM-yyyy HH.mm.ss") + ".xlsx";
//string randomFileName = Guid.NewGuid() + ".xlsx";
string FilePath = Server.MapPath("~/PDFReports/") + randomFileName;
//Here saving the file in xlsx
wb.SaveAs(FilePath);
wb.Save();
byte[] filedata = System.IO.File.ReadAllBytes(FilePath);
string contentType = MimeMapping.GetMimeMapping(FilePath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = randomFileName,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
please help in adding drop down lists to my excel file
after searching i found this solution to add drop down to excel cells from predefined list
var Regions = _dbContext.GetRegions(GetCurrentNeutralCultureId(), -1);
var RegionsfromDb = Regions.Select(x => x.Value + "- " + x.Text).ToList(); //extract needed data
var RegionsList = $"\"{String.Join(",", RegionsfromDb)}\""; //seperate items by comma
worksheet.Cell("B9").DataValidation.IgnoreBlanks = true;
worksheet.Cell("B9").DataValidation.InCellDropdown = true;
worksheet.Cell("B9").Value = "---";
worksheet.Cell("B9").DataValidation.List(RegionsList, true);
Related
I know there are many topics on the issue, but my requirements are more specific.. I'm using EF to select records into my project, and then export them to Excel. I've used This snippet code.
Let me explain what I'm trying to do. Given the following table(It's for simplification, as you will see in the code the table is a bit larger):
Name | Content
A "Content1"
A "Content2"
A "Content3"
B "other content"
......
When I export to excel, I don't want A to appear 3 times next to each content, I'd like to have only one "A" (which I was able to do) and merge the 3 cells (align them to the center too if possible) into one(without touching the Content column) .
This is my code:
public IActionResult Index()
{
var knownCampaigns = _repository.getDataForExport();
//return View(result);
string sWebRootFolder = _hostingEnvironment.WebRootPath;
string sFileName = #"demo.xlsx";
string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, sFileName);
FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
if (file.Exists)
{
file.Delete();
file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
}
using (ExcelPackage package = new ExcelPackage(file))
{
// add a new worksheet to the empty workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("CampaignMatches");
//First add the headers
worksheet.Cells[1, 2].Value = "Customer Name";
worksheet.Cells[1, 3].Value = "Guid";
worksheet.Cells[1, 4].Value = "Campaign Title";
worksheet.Cells[1, 5].Value = "Referrer Title";
worksheet.Cells[1, 6].Value = "Activity Date";
worksheet.Cells[1, 7].Value = "Is clicked?";
int counter = 2;
string oldGuid = "";
foreach (var campaign in knownCampaigns)
{
if (oldGuid == campaign.Guid || worksheet.Cells["C" + (counter - 1)].Value.ToString() == campaign.Guid)
{
oldGuid = campaign.Guid;
worksheet.Cells["A" + counter].Value = "";
worksheet.Cells["B" + counter].Value = "";
}
else
{
oldGuid = "";
worksheet.Cells["A" + counter].Value = campaign.customerName;
worksheet.Cells["B" + counter].Value = campaign.Guid;
}
worksheet.Cells["C" + counter].Value = campaign.campaignTitle;
worksheet.Cells["D" + counter].Value = campaign.reffererTitle;
worksheet.Cells["E" + counter].Value = campaign.activityDate;
worksheet.Cells["F" + counter].Value = campaign.is_clicked;
counter++;
}
package.Save(); //Save the workbook.
}
var result = PhysicalFile(Path.Combine(sWebRootFolder, sFileName), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Response.Headers["Content-Disposition"] = new ContentDispositionHeaderValue("attachment")
{
FileName = file.Name
}.ToString();
return result;
}
Right now, my Customer Name and Guid column only appears once as intended, but I don't know how to merge the cells together into one cell.
Image of current output:
[![enter image description here][2]][2]
Image of wanted output:
[![enter image description here][3]][3]
It looks like it's not that obvious. Looks like there is an Elements property on worksheet that you can add type of MergedCell. https://learn.microsoft.com/en-us/office/open-xml/how-to-merge-two-adjacent-cells-in-a-spreadsheet
If someone will face the same issue, I've managed to solve this using Merge attribute , I had to extract the positions of the start column index, row index and end row index & end column index.
var Wsc_Guid = worksheet.Cells[startRowIndex, guidIndex, startRowIndex + numOfSameRecords, guidIndex];//Select the correct cells for Guids
Wsc_Guid.Merge = true;
This is my code.
public static string LoadPackage(DirectoryInfo outputDir, string name)
{
FileInfo newFile = new FileInfo(outputDir.FullName + #"\test.xlsx");
if (newFile.Exists)
{
newFile.Delete();
newFile = new FileInfo(outputDir.FullName + #"\test.xlsx");
}
var format = new ExcelTextFormat();
format.Delimiter = '\t';
format.SkipLinesBeginning = 1;
using (ExcelPackage package = new ExcelPackage())
{
LoadSheet(package, outputDir, name);
package.SaveAs(newFile);
}
return newFile.FullName;
}
And after that i call LoadSheet method in order to fill my excel file from tsv file.
public static void LoadSheet(ExcelPackage package, DirectoryInfo
outputDir, string name)
{
var ws = package.Workbook.Worksheets.Add("Content");
var format = new ExcelTextFormat();
format.Delimiter = '\t';
format.SkipLinesBeginning = 2;
format.SkipLinesEnd = 1;
var range = ws.Cells["A1"].LoadFromText(new
FileInfo(outputDir.FullName + "\\" + name), format,
TableStyles.Medium27, false);
}
And this is my code on button click event
if (BrowseFileUpload.HasFile)
{
var name = BrowseFileUpload.PostedFile.FileName;
InputTextBox.Text = name;
LoadData.LoadPackage(new
System.IO.DirectoryInfo("C:\\Users\\Nemanja\\Downloads"), name);
InfoLabel.Text = "Your data has been imported!!!";
InfoLabel.ForeColor = System.Drawing.Color.Blue;
InfoLabel.Font.Size = 20;
}
Everything is ok i create new excel file, sheet save it but it does not load data that i need it to load inside excel file. It's only empty file or i get a error the file is corrupted recover what you can.
Can someone figure out what can be a problem based on my explanation and this code. Thank you all good people.
I think that the problem may well be with the format of your source data. I've put together the following sample, based on your code, and it works fine.
var outFile = Path.ChangeExtension(filePath, ".xlsx");
using (var p = new ExcelPackage())
{
var fmt = new ExcelTextFormat();
fmt.Delimiter = '\t';
fmt.SkipLinesBeginning = 2;
fmt.SkipLinesEnd = 1;
fmt.EOL = ((char)10).ToString(); // THIS LINE FIXED THE PROBLEM (UNIX NEWLINE)
var ws = p.Workbook.Worksheets.Add("Imported Text");
ws.Cells[1, 1].LoadFromText(new FileInfo(filePath), fmt, TableStyles.Medium27, false);
p.SaveAs(new FileInfo(outFile));
}
Try running your data through this and see if you get the same issue or not.
UPDATED
The problem was a unix-style newline in the file - EPPlus expects a windows-style newline by default
Initialize the worksheet:
public HttpResponseMessage ER_GenerateWBLWorksheet2()
{
ExcelPackage ExclPkg = new ExcelPackage();
ExcelWorksheet wsSheet1 = ExclPkg.Workbook.Worksheets.Add("Sheet1");
wsSheet1.Cells["A1"].Value = "ProductName";
wsSheet1.Cells["B1"].Value = "Price";
wsSheet1.Cells["C1"].Value = "ProductImageUrl";
wsSheet1.Cells["D1"].Value = "ProductUrl";
wsSheet1.Cells["E1"].Value = "StoreId";
wsSheet1.Cells["G1"].Value = "CategoryId";
wsSheet1.Cells["I1"].Value = "ColorId";
wsSheet1.Cells["K1"].Value = "FabricId";
wsSheet1.Cells["M1"].Value = "Gender";
Create Category list:
var categorylist = wsSheet1.DataValidations.AddListValidation(wsSheet1.Cells["G2:G500"].Address);
var categories = _categoryServices.GetAllCategory();
var categoryEntities = (categories != null) ? categories.ToList() : new List<CategoryEntity>();
for (int i = 0; i < categoryEntities.Count; i++)
{
categorylist.Formula.Values.Add(categoryEntities[i].CategoryName.ToString());
}
categorylist.ShowErrorMessage = true;
categorylist.ErrorTitle = "Error";
categorylist.Error = "Please select the Category from Dropdown";
wsSheet1.Cells["G2:G500"].Style.Locked = false;
Create color list:
var colorlist = wsSheet1.DataValidations.AddListValidation(wsSheet1.Cells["I2:I500"].Address);
var colors = _colorServices.GetAllColor();
var colorsEntities = (colors != null) ? colors.ToList() : new List<ColorEntity>();
for (int i = 0; i < colorsEntities.Count; i++)
{
colorlist.Formula.Values.Add(colorsEntities[i].ColorName.ToString());
}
colorlist.ShowErrorMessage = true;
colorlist.ErrorTitle = "Error";
colorlist.Error = "Please select the Color from Dropdown";
wsSheet1.Cells["I2:I500"].Style.Locked = false;
wsSheet1.Cells[wsSheet1.Dimension.Address].AutoFitColumns();
var filename = #"Inventory_" + DateTime.Now.ToString("M_dd_yyyy_H_M_s") + ".xlsx";
//string sPath = #"e:\" + filename;
var sPath = System.Web.Hosting.HostingEnvironment.MapPath("~/exportedfiles/" + filename);
Stream stream = File.Create(sPath);
ExclPkg.SaveAs(stream);
stream.Close();
string strServerPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["excelserverpath"]);
var sPathURL = (strServerPath + "exportedfiles/" + filename);
List<fileinfo> filelst = new List<fileinfo>();
fileinfo file = new fileinfo();
file.filename = filename;
file.fileurl = sPathURL;
//file.fileurl = sPath;
filelst.Add(file);
return new ResponseWrapper<fileinfo>(filelst, HttpStatusCode.OK, null, 0);
}
Using the above code I have created excel with drop down list, but my requirement is to select multiple values from drop down list. Is it possible using epplus library?
i'm using asp.net/c# with crystal report to export as PDF format, it is exporting Pdf fine. but we refereed the DB Table to Crystal Report so it is binding all data's to report not filter by parameter or select Formula model.
Here is My Code:
ReportDocument myreportdocument = new ReportDocument();
DataSet dsReport = new DataSet();
clsiCMSBLBase omenu = new clsiCMSBLBase();
string errMsg = string.Empty;
dsReport = omenu.GetListData(ref errMsg, parameters, "DBSP_PCPrintSlipRDLC");
myreportdocument = ReportFactory.GetReport(myreportdocument.GetType());
myreportdocument.Load(Server.MapPath("~/CrysReports/PCPrintSlipPUD.rpt"));
myreportdocument.SetParameterValue("UserID", Convert.ToInt32(2));
myreportdocument.SetDataSource(dsReport);
string dbUserName = ConfigurationManager.AppSettings["CrystalUserName"];
string dbPassword = ConfigurationManager.AppSettings["CrystalPassword"];
myreportdocument.SetDatabaseLogon(dbUserName, dbPassword);
cRY1.ReportSource = myreportdocument;
cRY1.SelectionFormula = " {TMP_PlotPCSlip.UserID} =" + 2;
cRY1.ReportSource = myreportdocument;
cRY1.HasCrystalLogo = false;
cRY1.DataBind();
cRY1.RefreshReport();
cRY1.BorderColor = System.Drawing.Color.Gray;
cRY1.BorderWidth = 1;
cRY1.BackColor = System.Drawing.Color.White;
cRY1.Style.Add("width", "100%");
//string filename = fact + "_" + flag + "_" + DateTime.Now.ToString("dd-MM-yyyy-HH-mm") + ".pdf";
myreportdocument.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, true, filename);
Response.End();
this Filter Code not filtering:
myreportdocument.SetParameterValue("UserID", Convert.ToInt32(2));
even i tried TableName.UserID but there is also not filter, so please share your experience..
Myreportdocument.RecordSelectionFormula="{table.column}=2"
I am trying create and write to a text file in a C# application using the following code
System.IO.Directory.CreateDirectory(Server.MapPath("~\\count"));
using (System.IO.FileStream fs = new System.IO.FileStream("~/count/count.txt", System.IO.FileMode.Create))
using (System.IO.StreamWriter sw = new System.IO.StreamWriter("~/count/count.txt"))
{
sw.Write("101");
}
string _count = System.IO.File.ReadAllText("~/count/count.txt");
Application["NoOfVisitors"] = _count;
but I get an error:
The process cannot access the file 'path' because it is being used by another process.
What is my error?
You're trying to open the file twice; your first using statements creates a FileStream that is not used, but locks the file, so the second using fails.
Just delete your first using line, and it should all work fine.
However, I'd recommend replacing all of that with File.WriteAllText, then there would be no using in your code, it'd be much simpler.
var dir = Server.MapPath("~\\count");
var file = Path.Combine(dir, "count.txt");
Directory.CreateDirectory(dir);
File.WriteAllText(file, "101");
var _count = File.ReadAllText(file);
Application["NoOfVisitors"] = _count;
private void ExportTextFile()
{
#region This region Used For Private variable.
string lblName = null;
string lblACN = null;
string lblIFSC = null;
string lblBCode = null;
string lblAdd1 = null;
string lblAdd2 = null;
string lblAdd3 = null;
string lblMobileNo = null;
string lblEmai = null;
#endregion
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/text";
StringBuilder Rowbind = new StringBuilder();
for (int i = 0; i < GrdAcc.Rows.Count; i++)
{
CheckBox Chk_Status = (CheckBox)GrdAcc.Rows[i].FindControl
("ChkStatus");
Label lbl_Status = (Label)GrdAcc.Rows[i].FindControl
("lblStatus");
Label lbl_Code = (Label)GrdAcc.Rows[i].FindControl
("lblEmpCode");
if (Chk_Status.Checked == true)
{
#region Fetching ACC Details From Database.
AccPL.Status = lbl_Status.Text;
AccPL.EmpCode = lbl_Code.Text;
DataTable dt = AccBL.ExportFileAcc(AccPL);
if (dt.Rows.Count > 0)
{
lblName = dt.Rows[0]["Name"].ToString().Trim();
lblACNo = dt.Rows[0]["ACNo"].ToString().Trim();
lblBCode = dt.Rows[0]["BCode"].ToString().Trim();
lblIFSC = dt.Rows[0]["IFSC"].ToString().Trim();
lblAdd1 = dt.Rows[0]["ADd1"].ToString() + dt.Rows[0]
["PPostTehsil"].ToString();
lblAdd2 = dt.Rows[0]["Add2"].ToString().Trim() +
dt.Rows[0]["PPIN"].ToString().Trim();
lblAdd3 = dt.Rows[0]["Add3"].ToString() + dt.Rows[0]
["State"].ToString().Trim();
lblMobileNo = dt.Rows[0]["MobileNo"].ToString().Trim();
lblEmai = dt.Rows[0]["Email"].ToString().Trim();
}
#endregion
#region Generating Text File .
if (ddlExportType.SelectedValue == "2")
{
Response.AddHeader("content-disposition", "
attachment;filename=" + DateTime.Now.ToString("ddMMyyhhmmss") + ".txt");
Rowbind.Append(lblName + "#" + lblAccNo + "#" + lblIFSC
+ "#" + "#" + "#" + "#" + "#" + "#" + lbl_Code.Text);
Rowbind.Append("\r\n");
}
#endregion
Response.Output.Write(Rowbind.ToString());
Response.Flush();
Response.End();
}