In crystal report ,2nd table from dataset not getting displayed - c#

In crystal report I am trying to display both tables of datatset ds ,but only table[0] is getting displayed in crystal report ,table[1] is not getting displayed why this is so ,I checked table[1] data is filled properly in that ,where is the problem?
private void ViewR_Load(object sender, EventArgs e)
{
String str = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = str + "\\images\\";
CrystalReportP objRpt;
// Creating object of our report.
objRpt = new CrystalReportP();
DataSetPatient ds = new DataSetPatient(); // .xsd file name
DataTable dt = DBHandling.GetPatient();
ds.Tables[0].Merge(dt);
DataTable dt1 = new DataTable();
//dt1.Columns.Add("Images", typeof(Bitmap));
dt1.Columns.Add("Images", typeof(Byte[]));
if (System.IO.Directory.Exists(path))
{
string[] allImg = System.IO.Directory.GetFiles(path);
foreach (string imgName in allImg)
{
drow = dt1.NewRow();
// define the filestream object to read the image
FileStream fs;
// define te binary reader to read the bytes of image
BinaryReader br;
// check the existance of image
// open image in file stream
fs = new FileStream(imgName, FileMode.Open);
// initialise the binary reader from file streamobject
br = new BinaryReader(fs);
// define the byte array of filelength
byte[] imgbyte = new byte[fs.Length + 1];
// read the bytes from the binary reader
imgbyte = br.ReadBytes(Convert.ToInt32((fs.Length)));
drow[0] = imgbyte;
// add the image in bytearray
dt1.Rows.Add(drow[0]);
// add row into the datatable
br.Close();
// close the binary reader
fs.Close();
// close the file stream
}
}
try
{
ds.Tables[1].Merge(dt1);
}
catch (Exception r)
{
}
objRpt.SetDataSource(ds);
crystalReportViewer1.ReportSource = objRpt;
}

In Field Explorer of Crystal report Just Cheking whether both tables added in its Database Field,If not than After adding It works Properly .

Related

I want to save image in jpg format from SQL Server database but when I download it , it has only 1KB size and cannot be opened

private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string SaveFileTo = "D:\\DA.jpg";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where enrollno='" + CboEnroll.Text + "' ", CN);
DR = cmd.ExecuteReader();
byte[] data = null;
while (DR.Read())
{
data = (byte[])DR["Photo"];
}
using (var fs = new FileStream(SaveFileTo, FileMode.Create, FileAccess.Write))
{
fs.Write(data,0,data.Length);
}
MessageBox.Show("Success");
}
I have run the code in the question, even it has some of not good coding practices, if the data in the photo column is not corrupted it should produce the image file.
so I have put down your code with proper enhancements that will flag you early before saving corrupted data.
private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ImageCodecInfo theJpgCodecInfo = ImageCodecInfo.GetImageEncoders()
.FirstOrDefault(encoder => encoder.MimeType == "image/jpeg");
var myEncoder = Encoder.Quality;
var myEncoderPrams = new EncoderParameters(1);
myEncoderPrams.Param[0] = new EncoderParameter(myEncoder, 100L);
string SaveFileTo = "D:\\DA";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where
enrollno=#Enrol;", CN);
cmd.Parameters.AddWithValue("#Enrol", CboEnroll.SelectedItem.ToString());
DR = cmd.ExecuteReader();
byte[] data = null;
int idx = 0;
while (DR.Read())
{
data = (byte[])DR["Photo"];
Image tempImage;
try
{
tempImage = ByteArrayToImage(data);
}
catch (Exception exc)
{
MessageBox.Show(exc.GetType().ToString()
+Environment.NewLine+exc.Message);
continue;
}
var tempBitmap = new Bitmap(tempImage);
var tempFname = "D:\\DA"+(idx++).ToString()+".jpg";
tempBitmap.Save(tempFname, theJpgCodecInfo, myEncoderPrams);
}
}
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
The enhancements that I suggested as follow:
As #derpirscher mentioned in his comment use parameters not string concatenation when building SQL commands and the easiest most lazy way to do it is Parameters.AddWithValue().
Use CboBox.SelectedItem.ToString in place of the .Text as been in your code.
instead of dumping the byte[] directly through a FileStream.Write() I transferred the byte array into Image() then into Bitmap().
this way if the byte[] (and hence the data in the db column photo) is not one of the binary formats the the class Image() can handle it will throw exception and I used that to show the related error.
Also, this way we over came some issues that may rise if we used Bitmap() directly if the data byte[] contains PNG format.
No matter what image format is stored in the photo column it will be legitimately re-encoded as Jpeg then saved.

How to display SQL Server database image base64 in Aspose Word Document

I am new in Aspose and I have the following issue:
I have images in a SQL Server 2008 database, stored as a Base64 strings. I would like to display them in a Word document using Aspose.
I have successfully exported the other data, but can't display the images. Can anyone help me please?
Thanks in advance for your support.
Here is my code:
private Document createDocs(Guid ? ID)
{
Document doc = new Document(HostingEnvironment.MapPath("~/Content/Template.doc"));
DataTable Order = ExecuteDataTable(inspID);
if (!(Order == null))
{
doc.MailMerge.FieldMergingCallback = new HandleMergeImageFieldFromBlob();
doc.MailMerge.ExecuteWithRegions(Order);
}
return doc;
}
public DataTable ExecuteDataTable(Guid? ID)
{
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyStringConnection"];
SqlConnection Conn = new SqlConnection(connectionString.ConnectionString);
try
{
Conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM blahblah, Conn);
cmd.Parameters.Add("#ID", SqlDbType.UniqueIdentifier).Value = ID;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.SelectCommand = cmd;
DataTable table = new DataTable();
da.Fill(table);
return table;
}
finally
{
if (!(Conn == null))
{
Conn.Close();
}
}
}
private void SendToBrowser (Document doc, string outputFormat, Page page)
{
MemoryStream stream = new MemoryStream();
doc.Save(stream, SaveFormat.Doc);
page.Response.Clear();
page.Response.ClearHeaders();
page.Response.ClearContent();
page.Response.ContentType = "application/doc";
page.Response.AddHeader("content-disposition", "attachment; filename=base_file.doc");
byte[] bytes = stream.GetBuffer();
page.Response.BinaryWrite(bytes);
page.Response.End();
}
public class HandleMergeImageFieldFromBlob : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
// Do nothing.
}
/// <summary>
/// This is called when mail merge engine encounters Image:XXX merge field in the document.
/// You have a chance to return an Image object, file name or a stream that contains the image.
/// </summary>
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
{
// The field value is a byte array, just cast it and create a stream on it.
var imageStream = new MemoryStream((byte[])e.FieldValue);
// Now the mail merge engine will retrieve the image from the stream.
e.ImageStream = imageStream;
}
}
To insert an image mail merge field into a document in Word, select Insert/Field command, then select MergeField and type Image:MyFieldName. Following code example shows how perform mail merge operation with Base64 image. Please check the modified code of IFieldMergingCallback.ImageFieldMerging.
public void mailmerge()
{
string base64String;
using (Image image = Image.FromFile(MyDir + #"image.png"))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
base64String = Convert.ToBase64String(imageBytes);
}
}
DataTable dt = new DataTable();
dt.Columns.Add("ImageData", typeof(string));
DataRow row1 = dt.NewRow();
row1["ImageData"] = base64String;
dt.Rows.Add(row1);
Document doc = new Document(MyDir + "in.docx");
doc.MailMerge.FieldMergingCallback = new HandleMergeImageFieldFromBlob();
doc.MailMerge.Execute(dt);
doc.Save(MyDir + "Out.docx");
}
public class HandleMergeImageFieldFromBlob : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
// Do nothing.
}
/// <summary>
/// This is called when mail merge engine encounters Image:XXX merge field in the document.
/// You have a chance to return an Image object, file name or a stream that contains the image.
/// </summary>
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
{
var imageStream = new MemoryStream((byte[])Convert.FromBase64String(e.FieldValue.ToString()));
// Now the mail merge engine will retrieve the image from the stream.
e.ImageStream = imageStream;
}
}
I work with Aspose as Developer evangelist.

how to get Image from DataSet

i have DataSet that contain Image.
i need to save this Image to File.
i try this:
SQL = ItemCode,PIC from ROW;
dsView = new DataSet();
adp = new SqlCeDataAdapter(SQL, Conn);
adp.Fill(dsView, "ROW");
adp.Dispose();
foreach (DataRow R in dsROW.Tables[0].Rows)
{
ItemCode = R["ItemCode"].ToString().Trim() ;
TEMP = R["PIC"].ToString().Trim();
Image image = R["PIC"] as Image;
if(image != null)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imagedata = ms.ToArray();
}
but image Always is null
and in TEMP i see System.Byte[]
need some help, thanks
Your R["PIC"] is an array or Bytes.
First, you try to apply ToString() to it, and you simply get System.Byte[].
Then, you try to cast it to Image. How is Byte[] supposed to cast to Image?
You need to create an Image from your Byte array:
dsView = new DataSet();
adp = new SqlCeDataAdapter(SQL, Conn);
adp.Fill(dsView, "ROW");
adp.Dispose();
foreach (DataRow R in dsROW.Tables[0].Rows)
{
ItemCode = R["ItemCode"].ToString().Trim();
using (var ms = new MemoryStream(R["PIC"]))
{
Image image = Image.FromStream(ms);
image.Save($"C:\\Output\\YourCustomPath\\{ItemCode}.jpeg", ImageFormat.Jpeg);
}
}
You need to read the data in sequential access mode. Here is an example I use to read binary data. See the use of
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
snippet:
string sql = "Select file_data from utils where util_id="+uID.ToString()+";";
SqlCommand cmd = new SqlCommand(sql, database._sqlConnection);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess); // CommandBehavior.SequentialAccess: read columns in order and every column only once!
int columnNr = 0;
byte[] filedata = null;
try
{
while (rdr.Read())
{
//load the binary data
if (rdr.IsDBNull(columnNr)) //is there any binary data? //LAST COLUMN!!!!!
filedata = null;
else
{
//read binary data
int bufferSize = 100; // Size of the BLOB buffer.
byte[] outbyte = new byte[bufferSize]; // The BLOB byte[] buffer to be filled by GetBytes.
long retval; // The bytes returned from GetBytes.
long startIndex = 0; // The starting position in the BLOB output.
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
// Reset the starting byte for the new BLOB.
startIndex = 0;
// Read the bytes into outbyte[] and retain the number of bytes returned.
retval = rdr.GetBytes(columnNr, startIndex, outbyte, 0, bufferSize);
// Continue reading and writing while there are bytes beyond the size of the buffer.
while (retval >0) //== bufferSize)
{
bw.Write(outbyte);
bw.Flush();
// Reposition the start index to the end of the last buffer and fill the buffer.
startIndex += bufferSize;
retval = rdr.GetBytes(columnNr, startIndex, outbyte, 0, bufferSize);
}
bw.Close();
filedata = ms.ToArray();
ms.Close();
}
}
}
catch (SqlException ex)

How to Save Excel File in a specific Folder

I am exporting excel file from database using following method.But i have one problem when i am exporting excel file than it is automatically downloading to download folder and i don't want this to be happen,I want my excel file to be downloaded in my project folder
var formsection = from fs in db.FormSections
join form in Form on fs.FormId equals form.FormId
select fs;
XLWorkbook wb = new XLWorkbook();
string sheetName = "ARTICLE"; //Give name for export file.
var Fs = wb.Worksheets.Add("FORMSECTION");
Fs.Cell(2, 1).InsertTable(formsection.ToList());// assign list here.
HttpContext.Response.Clear();
HttpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Response.AddHeader("content-disposition", String.Format(#"attachment;filename={0}.xlsx", sheetName.Replace(" ", "_")));
var filePath = Path.Combine(Server.MapPath("~/Content"));
using (MemoryStream memoryStream = new MemoryStream())
{
wb.SaveAs(memoryStream);
memoryStream.WriteTo(HttpContext.Response.OutputStream);
memoryStream.Close();
}
HttpContext.Response.End();
Here is an example that converts a datatable to a .csv file and save the file to the folder of your project for me its store the file in Domestic folder as the path given by me.
private void test(DataTable dt1) {
string csv = string.Empty;
foreach (DataColumn column in dt1.Columns)
{
//Add the Header row for CSV file.
csv += column.ColumnName + ',';
}
//Add new line.
csv += "\r\n";
foreach (DataRow row in dt1.Rows)
{
foreach (DataColumn column in dt1.Columns)
{
//Add the Data rows.
csv += row[column.ColumnName].ToString().Replace(",", ";") +',';
}
//Add new line.
csv += "\r\n";
}
string datetime = Convert.ToString(DateTime.Today.ToString("dd-MM-yyyy")).Trim();
string filepath = "C:\\Users\\Prateek\\Desktop\\MMR New 27-07 -\\Domestic\\";
string filename= #"BILLING_BOOK_NO" + "_4005" + "_"+datetime+".CSV";
string combinepath = filepath + filename;
System.IO.File.WriteAllText(combinepath,csv);
}`
You need to write the excel to your server first.
wb.SaveAs(filePath);
//encrypt the file
Encrypt(filePath);
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
memoryStream.Write(bytes, 0, (int)file.Length);
memoryStream.WriteTo(HttpContext.Response.OutputStream);
}
}
use code as below
public void ImportXLX()
{
string filePath = string.Format("{0}/{1}", Server.MapPath("~/Content/UploadedFolder"), #"C:\Users\Vipin\Desktop\Sheets\MyXL6.xlsx");
if (System.IO.File.Exists(filePath))
System.IO.File.Delete(filePath);
Request.Files["xlsFile"].SaveAs(filePath);
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
}

reading selected data from an excel and creating and writing to an xml in c#

I am having an .xls file containg 5 columns (id, name, address, phone, mobile) and respective values. I have to create a xml file programatically and write the 3 out of 5 column values only (id, name , mobile) in the xml file.
I am using below code to get the data from web and first writing it to an xls file which is working fine. However getting data from xls and creating and writing to xml is missing..
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(DownloadedxlsFilePath, FileMode.Create);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
fs.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
fs.Close();
stream.Close();
so there are two ways:
1. Get the whole data and select the required one and then create and write to an xml
2. Write the data to an .xls file easily using above code and then get the required data using C# logic and then write to xml.
Can any one help on either of above mentioned approach in c#.
This may help, but will require some modification on your part. I use the below code to retrieve data from an Excel file, write it to a datatable, and then iterate over each row in the datatable and write it out to a database table.
namespace CopyExcel
{
class Program
{
static void Main(string[] args)
{
var fileName = string.Format("{0}\\MaintList.xlsx", "C:\\Import");
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);
var db = new ModulesDataContext();
var adapter = new OleDbDataAdapter("SELECT * FROM [WCR$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "ExcelData");
DataTable ExcelData = ds.Tables["ExcelData"]; // datatable to store retrieved Excel data
var counter = 0;
foreach (DataRow row in ExcelData.Rows)
{
Module mod = new Module(); // this is the class built over my Module table
mod.SystemID = Convert.ToInt32(ExcelData.Rows[counter]["SysID"]);
mod.Module1 = ExcelData.Rows[counter]["Num"].ToString();
mod.Title = ExcelData.Rows[counter]["Title"].ToString();
mod.Type = "CAI";
// Save data to Module database table
db.Modules.InsertOnSubmit(mod);
db.SubmitChanges();
counter++;
}
}
}
}
You could modify so that instead of writing to datatable, you could output to XML:
var xElement = new XElement("systemid", Convert.ToInt32(ExcelData.Rows[counter]["SysID"]);
xElement.Add(new XElement("module", ExcelData.Rows[counter]["Num"].ToString());
xElement.Add(new XElement("title", ExcelData.Rows[counter]["Title"].ToString());
etc...
Of course, you'd be dealing with your own columns like id, name, and mobile.

Categories

Resources