PDA

View Full Version : سوال: چگونگی Export کردن دیتاگرید بصورت عکس کامل



Salar Ashgi
چهارشنبه 20 مرداد 1389, 22:09 عصر
سلام ، من بروش زیر میخوام تمام محتویات یه دیتاگرید رو بصورت یه عکس ذخیره کنم :



Graphics g = dataGridView1.CreateGraphics();
Bitmap bmp = new Bitmap(dataGridView1.Width, dataGridView1.Height, g);
dataGridView1.DrawToBitmap(bmp, new Rectangle(0, 0, dataGridView1.Width, dataGridView1.Height));
bmp.Save("D:\\dgv.bmp", System.Drawing.Imaging.ImageFormat.Bmp);


مثلا فرض کنیم دیتاگرید من 36 تا سطر داره ، عکسشم اینه :

http://salarcpp.persiangig.com/new_folder_3/pic_1.jpg

ولی خروجی این کد عکسی تولید میکنه که فقط شامل چند رکورد اول دیتاگرید هستش ، در
واقع عمل اسکرول رو انجام نمیده و فقط اون نمایشی که در حال حاضر از دیتاگرید هست رو تبدیل میکنه به عکس و نه کل دیتاگرید رو ، چطور میشه این مشکل رو برطرف کرد ؟!

خروجی عکس تولید شده :

http://salarcpp.persiangig.com/new_folder_3/dgv.jpg

با تشکر ./

zentex
پنج شنبه 21 مرداد 1389, 07:20 صبح
سلام ، من بروش زیر میخوام تمام محتویات یه دیتاگرید رو بصورت یه عکس ذخیره کنم :



Graphics g = dataGridView1.CreateGraphics();
Bitmap bmp = new Bitmap(dataGridView1.Width, dataGridView1.Height, g);
dataGridView1.DrawToBitmap(bmp, new Rectangle(0, 0, dataGridView1.Width, dataGridView1.Height));
bmp.Save("D:\\dgv.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
مثلا فرض کنیم دیتاگرید من 36 تا سطر داره ، عکسشم اینه :

http://salarcpp.persiangig.com/new_folder_3/pic_1.jpg

ولی خروجی این کد عکسی تولید میکنه که فقط شامل چند رکورد اول دیتاگرید هستش ، در
واقع عمل اسکرول رو انجام نمیده و فقط اون نمایشی که در حال حاضر از دیتاگرید هست رو تبدیل میکنه به عکس و نه کل دیتاگرید رو ، چطور میشه این مشکل رو برطرف کرد ؟!

خروجی عکس تولید شده :

http://salarcpp.persiangig.com/new_folder_3/dgv.jpg

با تشکر ./
میشه یه زحمتی بکشی ،اگه کارت درست شد کد کاملو بزاری چون من خیلی وقته درباره چیزی مثله این می گردم البته با خروجی از نوع کرل دراو
http://barnamenevis.org/forum/showthread.php?t=239169

vandermond
پنج شنبه 21 مرداد 1389, 09:52 صبح
سلام دوستان
از اين كد ميتونيد استفاده كنيد:

Bitmap bmp = new Bitmap(dataGridView1.Width,dataGridView1.Height);
Rectangle rec = new Rectangle(0, 0, dataGridView1.Width, dataGridView1.Height);
dataGridView1.DrawToBitmap(bmp, rec);
bmp.Save(@"G:\My Documents\My Pictures\b.bmp");

Salar Ashgi
پنج شنبه 21 مرداد 1389, 12:50 عصر
سلام دوستان
از اين كد ميتونيد استفاده كنيد:


مثل اینکه اصلا به روی سوال توجه نکردید !؟ مشکل اسکرول وجود داره !

Salar Ashgi
پنج شنبه 21 مرداد 1389, 15:04 عصر
سایر دوستان راه حلی برای رفع مشکل اسکرول در نظر دارند ؟!

vandermond
پنج شنبه 21 مرداد 1389, 15:30 عصر
:متعجب::متعجب::متعجب::متعجب: :متعجب: :متعجب:
من اصلا اين چيزايي كه نوشتيد رو نديدم فقط همون دوتا عكس رو ديدم. كدي هم نبود فكر ميكنم.:متعجب:
نكنه از امتيازات مديريتي استفاده كرديد:متفکر:.
شوخي كردم احتمالا مشكل از خودم بوده(ولي واقعا نديدم اصلا).
براي اين موضوع هم حتما بايد خود گريد باشه؟ خب داده هاش رو استفاده كنيد و توي يك جاي مناسب پياده كنيد.
يا يه چيز ابتكاري كه به نظرم مياد اينه كه يه لحظه گريد رو به اندازه اي بزرگ كنيد كه تمام داده ها ديده بشه. عكس بگيريد و بعد به حالت قبل برگردونيد. (البته ميدونم اصلا اصلا اصلا اصولي نيست)

ee_persian
پنج شنبه 21 مرداد 1389, 16:26 عصر
فکر کنم تو این لینک به جوابتون برسید ....


http://www.codeproject.com/KB/GDI-plus/DgridView2BitmapPckge.aspx

ee_persian
پنج شنبه 21 مرداد 1389, 16:29 عصر
اینم هست ....


http://www.c-sharpcorner.com/UploadFile/scottlysle/DGV2BMP01182007020129AM/DGV2BMP.aspx

اگه با دقت بخونین و قدم به قدم مراحلش رو انجام بدین مطمئن باشید جواب می گیرید .... خودم امتحان کردم درست بود ....

Salar Ashgi
پنج شنبه 21 مرداد 1389, 17:38 عصر
هر دوتاشون رو قبلا دیدم و هر دوتاشون هم مشکل اسکرول رو همچنان دارند !

mehdi.mousavi
جمعه 22 مرداد 1389, 15:04 عصر
سلام ، من بروش زیر میخوام تمام محتویات یه دیتاگرید رو بصورت یه عکس ذخیره کنم. ولی خروجی این کد عکسی تولید میکنه که فقط شامل چند رکورد اول دیتاگرید هستش ، در واقع عمل اسکرول رو انجام نمیده و فقط اون نمایشی که در حال حاضر از دیتاگرید هست رو تبدیل میکنه به عکس و نه کل دیتاگرید رو ، چطور میشه این مشکل رو برطرف کرد ؟!

سلام.
من کلا این روش Snapshot گرفتن از صفحه رو برای ایجاد گزارش نمی پسندم (مگه اینکه هدف دیگه ای داشته باشید). اما در هر حال، می تونید به این شیوه عمل کنید. ابتدا یک Bitmap بر اساس Size داده های موجود (تعداد Row های Grid و ارتفاع Header) می سازیم. بعد از اولین Row شروع میکنیم Snapshot گرفتن، اولین Snapshot بالای Target Bitmap قرار میگیره.

بعد به تعداد Rowهای Visible داده ها رو Scroll میکنیم تا داده های جدید روی صفحه نمایان بشه. حالا دوباره snapshot میگیریم از DataGridView و پس از Crop کردن Header تصویر رو به Target Bitmap اضافه میکنیم (در انتهای اون قرار میدیم). همینکارو به تعداد صفحات موجود در جدول تکرار میکنیم.

من یک کدی برای اینکار نوشتم، اما متوجه شدم یه ایراد کوچک داره. اونم اینکه بسته به تعداد Row ها و Visible بودن چند Row در آن واحد، ممکنه Page آخر درست محاسبه نشه. اینو لطفا خودتون درست کنید... اما برای شروع، میتونید از این کدی که نوشتم استفاده کنید:

//Ignore the scrollbar's width...
int width = this.dataGridView.Width - SystemInformation.VerticalScrollBarWidth;
int height = this.dataGridView.Height;

int columnHeaderHeight = this.dataGridView.ColumnHeadersHeight;

//Calculate total rows' height. If the rows are equally heighted, then we could
//easily multiply the first row's height by the total number of rows...
int totalRowsHeight = 0;
foreach (DataGridViewRow row in this.dataGridView.Rows)
totalRowsHeight += row.Height;

//Create the target bitmap...
using (Bitmap targetBitmap = new Bitmap(width, totalRowsHeight + columnHeaderHeight))
{
using (Graphics targetGraphics = Graphics.FromImage(targetBitmap))
{
int y = 0, totalVisibleRows = this.dataGridView.DisplayedRowCount(true);
for (int i = 0; i < this.dataGridView.Rows.Count; i += totalVisibleRows)
{
//Make sure that the i'th index is visible in the gridview...
this.dataGridView.FirstDisplayedScrollingRowIndex = i;
this.dataGridView.PerformLayout();

using (Bitmap bitmap = new Bitmap(width, height))
{
//Draw the bitmap to temporary memory...
this.dataGridView.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));

if (i > 0)
{
//Crop the header section and append the image to the target bitmap...
using (Bitmap croppedImage = bitmap.Clone(new Rectangle(0, columnHeaderHeight, width, height - columnHeaderHeight - 1), bitmap.PixelFormat))
{
targetGraphics.DrawImageUnscaledAndClipped(cropped Image, new Rectangle(0, y, croppedImage.Width, croppedImage.Height));
y += croppedImage.Height;
}
}
else
{
//Draw the image to the target bitmap...
targetGraphics.DrawImageUnscaledAndClipped(bitmap, new Rectangle(0, y, width, height));
y += height - 1;
}
}
}
}

targetBitmap.Save("D:\\dgv.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}


من با 100 تا Row آزمایش کردم و یه Bitmap به ارتفاع 2243 پیکسل بدون مشکل ساخته شد.
اما بازهم تکرار میکنم، این برنامه Page آخر رو بسته به شرایط ممکنه درست محاسبه نکنه! بنابراین به این مساله دقت کنید.

موفق باشید.

zentex
جمعه 22 مرداد 1389, 15:49 عصر
سلام.
من کلا این روش Snapshot گرفتن از صفحه رو برای ایجاد گزارش نمی پسندم (مگه اینکه هدف دیگه ای داشته باشید). اما در هر حال، می تونید به این شیوه عمل کنید. ابتدا یک Bitmap بر اساس Size داده های موجود (تعداد Row های Grid و ارتفاع Header) می سازیم. بعد از اولین Row شروع میکنیم Snapshot گرفتن، اولین Snapshot بالای Target Bitmap قرار میگیره.

بعد به تعداد Rowهای Visible داده ها رو Scroll میکنیم تا داده های جدید روی صفحه نمایان بشه. حالا دوباره snapshot میگیریم از DataGridView و پس از Crop کردن Header تصویر رو به Target Bitmap اضافه میکنیم (در انتهای اون قرار میدیم). همینکارو به تعداد صفحات موجود در جدول تکرار میکنیم.

من یک کدی برای اینکار نوشتم، اما متوجه شدم یه ایراد کوچک داره. اونم اینکه بسته به تعداد Row ها و Visible بودن چند Row در آن واحد، ممکنه Page آخر درست محاسبه نشه. اینو لطفا خودتون درست کنید... اما برای شروع، میتونید از این کدی که نوشتم استفاده کنید:

//Ignore the scrollbar's width...
int width = this.dataGridView.Width - SystemInformation.VerticalScrollBarWidth;
int height = this.dataGridView.Height;

int columnHeaderHeight = this.dataGridView.ColumnHeadersHeight;

//Calculate total rows' height. If the rows are equally heighted, then we could
//easily multiply the first row's height by the total number of rows...
int totalRowsHeight = 0;
foreach (DataGridViewRow row in this.dataGridView.Rows)
totalRowsHeight += row.Height;

//Create the target bitmap...
using (Bitmap targetBitmap = new Bitmap(width, totalRowsHeight + columnHeaderHeight))
{
using (Graphics targetGraphics = Graphics.FromImage(targetBitmap))
{
int y = 0, totalVisibleRows = this.dataGridView.DisplayedRowCount(true);
for (int i = 0; i < this.dataGridView.Rows.Count; i += totalVisibleRows)
{
//Make sure that the i'th index is visible in the gridview...
this.dataGridView.FirstDisplayedScrollingRowIndex = i;
this.dataGridView.PerformLayout();

using (Bitmap bitmap = new Bitmap(width, height))
{
//Draw the bitmap to temporary memory...
this.dataGridView.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));

if (i > 0)
{
//Crop the header section and append the image to the target bitmap...
using (Bitmap croppedImage = bitmap.Clone(new Rectangle(0, columnHeaderHeight, width, height - columnHeaderHeight - 1), bitmap.PixelFormat))
{
targetGraphics.DrawImageUnscaledAndClipped(cropped Image, new Rectangle(0, y, croppedImage.Width, croppedImage.Height));
y += croppedImage.Height;
}
}
else
{
//Draw the image to the target bitmap...
targetGraphics.DrawImageUnscaledAndClipped(bitmap, new Rectangle(0, y, width, height));
y += height - 1;
}
}
}
}

targetBitmap.Save("D:\\dgv.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}


من با 100 تا Row آزمایش کردم و یه Bitmap به ارتفاع 2243 پیکسل بدون مشکل ساخته شد.
اما بازهم تکرار میکنم، این برنامه Page آخر رو بسته به شرایط ممکنه درست محاسبه نکنه! بنابراین به این مساله دقت کنید.

موفق باشید.
سلام ویژه به مدیر بخش(به به چه سعادتی:لبخند:)
قربان بنده با شما کاملاً موافق هستم"من کلا این روش Snapshot گرفتن از صفحه رو برای ایجاد گزارش نمی پسندم"
راستیتش این موضوع برمی گرده به یکی از انواع گرفتن خروجی(منظور انواع Export)
بنده شخصاًکل اینترنتو گشتم همه نوع اکسپورت . doc.|xls.|txt.|html و سه تا نقطه وجود داره الا export فایل ها گرافیکی
آقا ما اگه بخوایم اطلاعات table بانک اطلاعاتیمون (sql)رو با پسوندای cdr کرل یا psd فتوشاپ export کنیم می بایست چیکار کنیم ؟؟؟!!
یعنی یه حرفه ای نیست که حالا کدش نیست بشینه بنویسه ؟؟؟!

mehdi.mousavi
جمعه 22 مرداد 1389, 16:33 عصر
سلام ویژه به مدیر بخش(به به چه سعادتی:لبخند:) قربان بنده با شما کاملاً موافق هستم"من کلا این روش Snapshot گرفتن از صفحه رو برای ایجاد گزارش نمی پسندم"
راستیتش این موضوع برمی گرده به یکی از انواع گرفتن خروجی(منظور انواع Export) بنده شخصاًکل اینترنتو گشتم همه نوع اکسپورت . doc.|xls.|txt.|html و سه تا نقطه وجود داره الا export فایل ها گرافیکی آقا ما اگه بخوایم اطلاعات table بانک اطلاعاتیمون (sql)رو با پسوندای cdr کرل یا psd فتوشاپ export کنیم می بایست چیکار کنیم ؟؟؟!! یعنی یه حرفه ای نیست که حالا کدش نیست بشینه بنویسه ؟؟؟!

سلام ،
کدی که نوشتم درست کار میکنه فقط تنبلیم اومد بشینم محاسبه کنم ببینم Page آخر رو چطوری و از کجای Bitmap باید Crop کنم. و الا مابقیش مشکلی نداره.

اما در مورد Export به CDR و PSD و ... طبیعی هستش که Tabular Data ها اگر به Vector تبدیل بشن، هیچ ارزشی ندارن. ممکنه در یک کاربرد خاص، تبدیل یک عبارت به Mesh قابل خونده شدن توسط 3DS معنا داشته باشه، اما این چیزی نیست که مورد استفاده اکثریت باشه. چنین تبدیلی روی داده ها، ارزش داده ای این اطلاعات رو از بین میبره و عملا اونو تبدیل به Pile ای از نقاط و ... میکنه که فاقد ارزش هستن. به همین دلیل هستش که چنین تکه کدهایی عموما یافت نمیشه و کسی حاضر نیست وقتش رو بابت نوشتن چنین کدی صرف کنه.

موفق باشید.

Salar Ashgi
جمعه 22 مرداد 1389, 18:00 عصر
سلام.
من کلا این روش Snapshot گرفتن از صفحه رو برای ایجاد گزارش نمی پسندم (مگه اینکه هدف دیگه ای داشته باشید). اما در هر حال، می تونید به این شیوه عمل کنید. ابتدا یک Bitmap بر اساس Size داده های موجود (تعداد Row های Grid و ارتفاع Header) می سازیم. بعد از اولین Row شروع میکنیم Snapshot گرفتن، اولین Snapshot بالای Target Bitmap قرار میگیره.

بعد به تعداد Rowهای Visible داده ها رو Scroll میکنیم تا داده های جدید روی صفحه نمایان بشه. حالا دوباره snapshot میگیریم از DataGridView و پس از Crop کردن Header تصویر رو به Target Bitmap اضافه میکنیم (در انتهای اون قرار میدیم). همینکارو به تعداد صفحات موجود در جدول تکرار میکنیم.

من یک کدی برای اینکار نوشتم، اما متوجه شدم یه ایراد کوچک داره. اونم اینکه بسته به تعداد Row ها و Visible بودن چند Row در آن واحد، ممکنه Page آخر درست محاسبه نشه. اینو لطفا خودتون درست کنید... اما برای شروع، میتونید از این کدی که نوشتم استفاده کنید:


ممنون از کد کاربردی تون ، جناب موسوی من برای دیتاگرید زیر اینکارو انجام دادم :

http://salarcpp.persiangig.com/new_folder_3/dgv_1.png



private void Form1_Load(object sender, EventArgs e)
{

for (int i = 65; i <= 90; i++)
{
dataGridView1.Rows.Add(i.ToString(), ((char)(i)).ToString());
}
}


عکس خروجی :

http://salarcpp.persiangig.com/new_folder_3/dgv_3.png

همانطور که مشاهده میکنید شماره های 73 و 82 موجود نیستند (همانطور که خودتون ذکر کردین) ،
ممنون میشم اگه برای حل این مشکل هم کمکی کنید ./
با تشکر .

mohsen_csharp
جمعه 22 مرداد 1389, 22:56 عصر
سلام
این یه نمونه مثال هست که قابلیت print و ذخیره به صورت عکس از کنترل هایی چون
dataGridView و treeView و listView و propertyGrid و تمام کنترل های ساده را دارد
اگه سوالی بود در خدمتیم

razavi_university
شنبه 23 مرداد 1389, 01:20 صبح
من این مشکل رو برای کل فرم داشتم و نتونستم راه خوبی واسش پیدا کنم، ولی برای DataGrid و کنترل های اینچنینی( listboxو...) میتونین مشابه نرم افزار های Reporter کار کنید

http://www.codeproject.com/KB/printing/PrintingFormReport/pfrimg1.gif

http://www.codeproject.com/KB/printing/PrintingFormReport.aspx

http://www.codeproject.com/KB/grid/DataGridPrinter/preview.gif

http://www.codeproject.com/KB/grid/DataGridPrinter.aspx


نمونه های مشابه دیگری میتونین در Codeprojct پیدا کنید

موفق باشید

Salar Ashgi
شنبه 23 مرداد 1389, 09:49 صبح
دوست عزیز mohsen_csharp (http://www.barnamenevis.org/forum/member.php?u=36508) ،ممنون از نمونه بسیار زیبایی که ارائه کردین ، بسیار پر محتوا .
خیلی وقت بود که دنبال چنین چیزی بودم ! کاملا همونی بود که من میخواستم .