Change datasource using bartender dynamically using c# - c#

I'm populating fields data from database with bartender but I'm not able to do same while changing database from code,
e.g. There is a template called TestLBL.btw and in the template we have configured database field say TestDB.Name field now I've another database say TestDB2 and that have exact same fields as TestDB now I just wanted to print label with same field with different database(TestDB2) using c# code but that doesn't works :(
below is my sample code :
btnEngine = new Engine();
btnEngine.Start();
lblDoc = btnEngine.Documents.Open(ConfigurationManager.AppSettings["BarTenderTemplate_Path"] + templateName);
var msg = new Messages();
var resolution = new Resolution(300);
string connectString = ConfigurationManager.ConnectionStrings["TestDB2"].ConnectionString;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectString);
lblDoc.DatabaseConnections[0].Name = builder.InitialCatalog;
lblDoc.DatabaseConnections[0].Server = builder.DataSource;
lblDoc.DatabaseConnections[0].UserID = builder.UserID;
lblDoc.DatabaseConnections[0].SetPassword(builder.Password);
lblDoc.DatabaseConnections.SetDatabaseConnection(lblDoc.DatabaseConnections[0]);
lblDoc.DatabaseConnections.QueryPrompts["pRec_Key"].Value = Rec_key.ToString();
lblDoc.DatabaseConnections.QueryPrompts["pImage_Path"].Value = Image_Path;
var fileName = templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";
var fileFullPath = Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]) + "\\" + templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";
var result = lblDoc.ExportPrintPreviewToFile(Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]), fileName, ImageType.PDF
, ColorDepth.ColorDepth24bit, resolution, Color.White, OverwriteOptions.Overwrite, true, true, out msg);
lblDoc.Close(SaveOptions.SaveChanges);
It throws an error in below line, without any inner exception,
var result = lblDoc.ExportPrintPreviewToFile(Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]), fileName, ImageType.PDF
, ColorDepth.ColorDepth24bit, resolution, Color.White, OverwriteOptions.Overwrite, true, true, out msg);
Any help would be appreciated.!

I could not comment the post so i'll ask my question here:
What is the error message in this line?
var result =
lblDoc.ExportPrintPreviewToFile(
Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]),
fileName,
ImageType.PDF,
ColorDepth.ColorDepth24bit,
resolution,
Color.White,
OverwriteOptions.Overwrite, true, true, out msg);
Did you set up TestDB2 in your BTW file database?
string connectString = ConfigurationManager.ConnectionStrings["TestDB2"].ConnectionString;
Did your fileName valid?
var fileName = templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";

Related

Add drop down list (ddl) in excel using OpenXML library

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);

EzAPI - SSIS Set EzOleDbDestination Error output configuration

I am creating a C# Program to generate a SSIS package, does anyone know how to set the ErrorOutput property of an EzOleDbDestination object to "Redirect Row"?
Edit :
EzOleDbDestination db_dest = new EzOleDbDestination(dataFlow)
{
Name = "Destination " + File_Name,
Connection = oldb_connection,
Table = "[dbo].[" + File_Name + "]"
};
EzOleDbDestination db_dest_clean_error = new EzOleDbDestination(dataFlow)
{
Name = "Destination " + File_Name + "_CleanError",
Connection = oldb_connection,
Table = "[dbo].[" + File_Name + "_CleanError]"
};
db_dest.AttachTo(file_source);
db_dest_clean_error.AttachTo(db_dest);
db_dest.LinkAllInputsToOutputs();
db_dest_clean_error.LinkAllInputsToOutputs();
dataFlow.AttachTo(Sql_Create);
package.SaveToFile("C:\\Users\\LGuerin\\Desktop\\Package_" + Engagement + ".dtsx"); ;
These two lines make it work, Thank you billinkc for your answers!

what is the solution for Crystal Report Filter option in C#

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"

Affecting Specific Records Within Crystal Report

I have a Function that, when activated, iterates through the Crystal Report it is attached to, copies it to a pdf, then mails the entirety of it to a client once per identifying field.
They want to receive a pdf of records grouped by ID, for each ID in the Report, omitting some of a specific ID. I have no idea how to break the Report down into smaller Reports, though, or even where to begin if that's possible in the first place.
I am Creating Each Pdf for individual user and saving to my Google Driver also emailing using SendGrip Api.
I have used this code inside page.Aspx -> aspx.cs file.
//0. Here i am getting list users as an Object:
OpsManagementController OM = new OpsManagementController();
//1. Getting Users List:
var result = OM.UsersGetforInvoice();
//2. Creating folder for Invoices:
string folderName = #"D:\Google Drive\MonthlyInvoices";
string fileName = ("Invoices_" + DateTime.Now.ToString("yyyy-MM-dd").ToString());
string pathString = System.IO.Path.Combine(folderName, fileName);
System.IO.Directory.CreateDirectory(pathString);
string folderNameEmail = #"D:\Google Drive\MonthlyInvoices\Email";
string fileNameEmail = ("Invoices_" + DateTime.Now.ToString("yyyy-MM-dd").ToString());
string pathStringEmail = System.IO.Path.Combine(folderNameEmail, fileNameEmail);
System.IO.Directory.CreateDirectory(pathStringEmail);
//3. Generating invoices by user name:
for (int i = 0; i < result.UserDetail.Count; i++)
{
var userId = result.UserDetail[i].UserID;
var userEmail = result.UserDetail[i].Email;
var userName = result.UserDetail[i].FullName;
userName = userName.Replace(#"C\O", "CO");
userName = userName.Replace(#"C/O", "CO");
// Directories for reports:
var invoicePath = "D:/Google Drive/MonthlyInvoices/" + fileName + "/" + userId + " " + userName + ".pdf";
var invoicePath_email = "D:/Google Drive/MonthlyInvoices/Email/" + fileNameEmail + "/" + userId + " " + userName + ".pdf";
report2.SetParameterValue("UserID", result.UserDetail[i].UserID);
report2.ExportToDisk(ExportFormatType.PortableDocFormat, invoicePath);
// using sendgrip Api :
EmailUtils.SendEmail_Att(
new string[] { userEmail }, //TO : userEmail
new string[] { "email#gmail.com" }, //
invoiceSubject,
invoiceBody,
invoicePath_email
);
}

Getting "The process cannot access the file because it is being used by another process" when saving multiple files from the request stream

I am using the HTML5 canvas element and the new HTML5 file i\o function to drop multiple files on it and have them upload. It works fine, but now I need to generate a new filename if no files are in the destination directory (It's a 7 digit integer) or get the name of the last uploaded file, convert it to int32 and increment that by one for every new file being uploaded to the same directory. This is where the GetFileName(dir); comes in. The first image always uploads fine but the problem begins once the second file is saved and the process hits ImageJob.Build(), I presume this is because once the new file is starting to write, the GetFile() method runs for second file in line simultaneously and is checking for last written file, which is still being written and this creates the conflict. How can I fix this, maybe I can somehow itterate with a foreach over the Request.InputStream data or implement some kind process watch that waits for the process to finish?
Update: I tried using TempData to store the generated filename, and just increment on the int value in TempData for all the next file names and it appears to do better, gets more images in but still errors at some point. But TempData is not for that as it gets erased after each read, reassigning to it again does not help. Maybe I'll try storing it in session.
The process cannot access the file 'C:\Users\Admin\Documents\Visual Studio
2010\Projects\myproj\myproj\Content\photoAlbums\59\31\9337822.jpg'
because it is being used by another process.
public PartialViewResult Upload()
{
string fileName = Request.Headers["filename"];
string catid = Request.Headers["catid"];
string pageid = Request.Headers["pageid"];
string albumname = Request.Headers["albumname"];
var dir = "~/Content/photoAlbums/" + catid + "/" + pageid + "/" + (albumname ?? null);
var noex = GetFileName(dir);
var extension = ".jpg";
string thumbFile = noex + "_t" + extension;
fileName = noex + extension;
byte[] file = new byte[Request.ContentLength];
Request.InputStream.Read(file, 0, Request.ContentLength);
string imgdir;
string thumbimgdir;
string imageurl;
if (albumname != null)
{
imgdir = Server.MapPath("~/Content/photoAlbums/" + catid + "/" + pageid + "/" + albumname + "/" + fileName);
thumbimgdir = Server.MapPath("~/Content/photoAlbums/" + catid + "/" + pageid + "/" + albumname + "/" + thumbFile);
imageurl = "/Content/photoAlbums/" + catid + "/" + pageid + "/" + albumname + "/" + thumbFile;
}
else
{
imgdir = Server.MapPath("~/Content/photoAlbums/" + catid + "/" + pageid + "/" + fileName);
thumbimgdir = Server.MapPath("~/Content/photoAlbums/" + catid + "/" + pageid + "/" + thumbFile);
imageurl = "/Content/photoAlbums/" + catid + "/" + pageid + "/" + thumbFile;
}
ImageJob b = new ImageJob(file, imgdir, new ResizeSettings("maxwidth=1024&maxheight=768&format=jpg")); b.CreateParentDirectory = true; b.Build();
ImageJob a = new ImageJob(file, thumbimgdir, new ResizeSettings("w=100&h=100&mode=crop&format=jpg")); a.CreateParentDirectory = true; a.Build();
ViewBag.CatID = catid;
ViewBag.PageID = pageid;
ViewBag.FileName = fileName;
return PartialView("AlbumImage", imageurl);
}
public string GetFileName(string dir)
{
var FullPath = Server.MapPath(dir);
var dinfo = new DirectoryInfo(FullPath);
string FileName;
if (dinfo.Exists)
{
var Filex = dinfo.EnumerateFiles().OrderBy(x => x.Name).LastOrDefault();
FileName = Filex != null ? Path.GetFileNameWithoutExtension(Filex.Name) : null;
if (FileName != null)
{
FileName = FileName.Contains("_t") ? FileName.Substring(0, FileName.Length - 2) : FileName;
int fnum;
Int32.TryParse(FileName, out fnum);
FileName = (fnum + 1).ToString();
if (fnum > 999999) { return FileName; } //Check that TryParse produced valid int
else
{
var random = new Random();
FileName = random.Next(1000000, 9999000).ToString();
}
}
else
{
var random = new Random();
FileName = random.Next(1000000, 9999000).ToString();
}
}
else
{
var random = new Random();
FileName = random.Next(1000000, 9999000).ToString();
}
return FileName;
}
You simply cannot use the Random class if you want to generate unique filenames. It uses the current time as the seed, so two exactly concurrent requests will always produce the same 'random' number.
You could use a cryptographic random number generator,
but you would still have to ensure that (a) only one thread would generate it at a time, and (b) you used a sufficiently long identifier to prevent the Birthday paradox.
Thus, I suggest that everyone use GUID identifiers for their uploads, as they solve all of the above issues inherently (I believe an OS-level lock is used to prevent duplicates).
Your method also doesn't handle multiple file uploads per-request, although that may be intentional. You can support those by looping through Request.Files and passing each HttpPostedFile instance directly into the ImageJob.
Here's a simplified version of your code that uses GUIDs and won't encounter concurrency issues.
public PartialViewResult Upload()
{
string albumname = Request.Headers["albumname"];
string baseDir = "~/Content/photoAlbums/" + Request.Headers["catid"] + "/" + Request.Headers["pageid"] + "/" (albumname != null ? albumname + "/" : "");
byte[] file = new byte[Request.ContentLength];
Request.InputStream.Read(file, 0, Request.ContentLength);
ImageJob b = new ImageJob(file, baseDir + "<guid>.<ext>", new ResizeSettings("maxwidth=1024&maxheight=768&format=jpg")); b.CreateParentDirectory = true; b.Build();
ImageJob a = new ImageJob(file, baseDir + "<guid>_t.<ext>", new ResizeSettings("w=100&h=100&mode=crop&format=jpg")); a.CreateParentDirectory = true; a.Build();
//Want both the have the same GUID? Pull it from the previous job.
//string ext = PathUtils.GetExtension(b.FinalPath);
//ImageJob a = new ImageJob(file, PathUtils.RemoveExtension(a.FinalPath) + "_t." + ext, new ResizeSettings("w=100&h=100&mode=crop&format=jpg")); a.CreateParentDirectory = true; a.Build();
ViewBag.CatID = Request.Headers["catid"];
ViewBag.PageID = Request.Headers["pageid"];
ViewBag.FileName = Request.Headers["filename"];
return PartialView("AlbumImage", PathUtils.GuessVirtualPath(a.FinalPath));
}
If the process is relatively quick (small files) you could go in a loop, check for that exception, sleep the thread for a couple of seconds, and try again (up to a maximum number of iterations). One caveat is that if the upload is asynchronous you might miss a file.
A couple of other suggestions:
Make the GetFileName to be a private method so that it doesn't get triggered from the web.
The OrderBy in the Filex query might not do what you expect once the it goes to 8 digits (possible if the first Random() is a very high number).
The Random() should probably be seeded to produce better randomness.

Categories

Resources