【背景】
之前写的,用于抓取Amazon的Hot Deal的数据。
【AmazonHotDeal 代码分享】
1.截图:
2.完整项目代码下载:
3.代码分享:
(1)frmAmazonHotDeal.cs
/*
* [Function]
* Amazon Hot Deal search
*
* [Date]
* 2013-06-16
*
* [Author]
* Crifan Li
*
* [Contact]
* https://www.crifan.com/contact_me
*
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Net;
using Sgml;
using System.Xml;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
namespace AmazonHotDeal
{
public partial class frmAmazonHotDeal : Form
{
category mainCategory;
List<category.categoryItem> mainCategoryList;
public crifanLib crifanLib;
public struct amazonProductInfo
{
public string category;
public string productId;
public string title;
public bool isTop100; //http://www.amazon.com/gp/bestsellers/hi/ref=pd_dp_ts_hi_1
public string listPrice;
public string salePrice;
public string savingPrice;
public string savingPercentage;
//public string comm;
public string rating;
public string reviews;
};
public frmAmazonHotDeal()
{
//!!! for load embedded dll: (1) register resovle handler
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
InitializeComponent();
crifanLib = new crifanLib();
}
//for load embedded dll
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
dllName = dllName.Replace(".", "_");
if (dllName.EndsWith("_resources")) return null;
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
byte[] bytes = (byte[])rm.GetObject(dllName);
return System.Reflection.Assembly.Load(bytes);
}
void initProductInfoGridView()
{
dgvProductInfo.ColumnCount = 10;
dgvProductInfo.RowHeadersWidth = 60;
dgvProductInfo.RowHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgvProductInfo.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
dgvProductInfo.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dgvProductInfo.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
//(1)Category
dgvProductInfo.Columns[0].HeaderText = "Category";
//dgvProductInfo.Columns[0].Width = 250;
//(2)Product ID
dgvProductInfo.Columns[1].HeaderText = "Product ID";
//dgvProductInfo.Columns[1].Width = 200;
//(3)Title
dgvProductInfo.Columns[2].HeaderText = "Title";
//dgvProductInfo.Columns[2].Width = 200;
//(4)Is Top 100
dgvProductInfo.Columns[3].HeaderText = "Is Top 100";
//dgvProductInfo.Columns[3].Width = 100;
//(5)List Price
dgvProductInfo.Columns[4].HeaderText = "List Price";
//dgvProductInfo.Columns[4].Width = 110;
//(6)Sale Price
dgvProductInfo.Columns[5].HeaderText = "Sale Price";
//dgvProductInfo.Columns[4].Width = 110;
//(7)Savings
dgvProductInfo.Columns[6].HeaderText = "Savings";
//dgvProductInfo.Columns[4].Width = 110;
//(8)Savings %
dgvProductInfo.Columns[7].HeaderText = "Savings %";
//dgvProductInfo.Columns[4].Width = 110;
//(9)Rating
dgvProductInfo.Columns[8].HeaderText = "Rating";
//dgvProductInfo.Columns[4].Width = 110;
//(10)Reviews
dgvProductInfo.Columns[9].HeaderText = "Reviews";
//dgvProductInfo.Columns[4].Width = 110;
}
private void frmAmazonHotDeal_Load(object sender, EventArgs e)
{
initProductInfoGridView();
mainCategory = new category();
mainCategoryList = mainCategory.getMainCategoryList();
//foreach (category.categoryItem singleMainCategory in mainCategoryList)
//{
// cmbMainCatetory.Items.Add(singleMainCategory);
//}
cmbMainCatetory.DataSource = mainCategoryList;
cmbMainCatetory.DisplayMember = "name";
cmbMainCatetory.SelectedIndex = -1;
}
private void cmbMainCatetory_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbMainCatetory.SelectedIndex >= 0)
{
//category.categoryItem selectedMainCategory = (category.categoryItem)cmbMainCatetory.Items[cmbMainCatetory.SelectedIndex];
category.categoryItem selectedMainCategory = (category.categoryItem)cmbMainCatetory.SelectedItem;
List<category.categoryItem> subCategoryList = selectedMainCategory.subCategoryList;
cmbSubCategory.DataSource = subCategoryList;
cmbSubCategory.DisplayMember = "name";
cmbSubCategory.SelectedIndex = -1;
//foreach (category.categoryItem singleSubCategory in subCategoryList)
//{
// cmbSubCategory.Items.Add(singleSubCategory);
//}
}
else
{
cmbSubCategory.DataSource = null;
cmbSubCategory.DisplayMember = null;
//cmbSubCategory.Items.Clear();
}
}
category.categoryItem getCurrentSelectedCategory()
{
category.categoryItem curSelectedCategory = new category.categoryItem();
if (cmbSubCategory.SelectedIndex >= 0)
{
//has selected some sub category
curSelectedCategory = (category.categoryItem)cmbSubCategory.SelectedItem;
}
else
{
if (cmbMainCatetory.SelectedIndex >= 0)
{
//not select any sub category
//so use the corresponding main category
curSelectedCategory = (category.categoryItem)cmbMainCatetory.SelectedItem;
}
}
return curSelectedCategory;
}
XmlDocument htmlToXmlDoc(string html)
{
// setup SgmlReader
Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader();
sgmlReader.DocType = "HTML";
sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
//sgmlReader.InputStream = reader;
sgmlReader.InputStream = new StringReader(html);
// create document
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.XmlResolver = null;
doc.Load(sgmlReader);
return doc;
}
//draw the row index
void drawRowHeaderNumer(DataGridView dgvValue)
{
for (int index = 0; (index <= (dgvValue.Rows.Count - 1)); index++)
{
int number = index + 1;
dgvValue.Rows[index].HeaderCell.Value = String.Format("{0}", number);
}
}
void saveEachProduct(amazonProductInfo productInfo)
{
dgvProductInfo.Rows.Add(
productInfo.category,
productInfo.productId,
productInfo.title,
productInfo.isTop100?"yes":"no",
productInfo.listPrice,
productInfo.salePrice,
productInfo.savingPrice,
productInfo.savingPercentage,
productInfo.rating,
productInfo.reviews);
drawRowHeaderNumer(dgvProductInfo);
}
//void processEachProductNode(category.categoryItem curSelCategory, XmlNode singleProductNode)
void processEachProductNode(string categoryName, XmlNode singleProductNode)
{
amazonProductInfo productInfo = new amazonProductInfo();
//category name
//productInfo.category = curSelCategory.Name;
productInfo.category = categoryName;
//product id
productInfo.productId = "N/A";
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
/*
<div class="zg_itemImage_normal"><a href="http://www.amazon.com/Hamilton-Beach-25475-Breakfast-Sandwich/dp/B00BTIUYOO/ref=zg_bsnr_appliances_1/191-0874592-3518518
"><img src="http://ecx.images-amazon.com/images/I/41E3PVWxhML._SL160_SL160_.jpg" alt="Hamilton Beach 25475 Breakfast Sandwich Maker, Gray" title="Hamilton Beach 25475 Breakfast Sandwich Maker, Gray" onload="if (typeof uet == 'function') { uet('af'); }"/></a></div>
*/
//XmlNode itemImageNode = singleProductNode.SelectSingleNode(".//div[@class='zg_itemImage_normal']/a[@href]");
//special
//http://www.amazon.com/gp/new-releases/appliances/3741521/ref=zg_bsnr_nav_la_1_la
//7th item, contain nothing, only contain pic
//<img src="http://ecx.images-amazon.com/images/I/41P-wTTZgFL._SL160_SL160_.jpg"/></a></div></div><div class="zg_itemRightDiv_normal"><div class="zg_rankLine"><span class="zg_rankNumber">7.</span><span class="zg_rankMeta"></span></div><div class="zg_itemPriceBlock_normal">
//now html change to
//<div class="zg_image">
//<div class="zg_itemImageImmersion">
// <a href="http://www.amazon.com/Creative-Options-700-769-Shoulder-Organizers/dp/B00CB38TUC/ref=zg_bsnr_12896361_1/181-1310935-2535815">
// <div class="valign_wrapper" style="padding:10px 0 10px 0">
// <img src="http://ecx.images-amazon.com/images/I/51E3EHv1h2L._SL160_SL150_.jpg" alt="Creative Options 700-769 Soft Sided S..." title="Creative Options 700-769 Soft Sided S..." onload="if (typeof uet == 'function') { uet('af'); }" />
// </div></a>
//</div>
//</div>
XmlNode itemImageNode = singleProductNode.SelectSingleNode(".//div[@class='zg_itemImageImmersion']/a[@href]");
string productUrl = itemImageNode.Attributes["href"].Value; //"\n\n\n\n\n\n\nhttp://www.amazon.com/Creative-Options-700-769-Shoulder-Organizers/dp/B00CB38TUC/ref=zg_bsnr_12896361_1/190-5936290-7962445\n"
productUrl = HttpUtility.HtmlDecode(productUrl.Trim()); //"http://www.amazon.com/Creative-Options-700-769-Shoulder-Organizers/dp/B00CB38TUC/ref=zg_bsnr_12896361_1/190-5936290-7962445"
//http://www.amazon.com/Hamilton-Beach-25475-Breakfast-Sandwich/dp/B00BTIUYOO/ref=zg_bsnr_appliances_1/191-0874592-3518518
string productId = "";
if (crifanLib.extractSingleStr(@"/([A-Z\d]+)/ref=", productUrl, out productId))
{
productInfo.productId = productId;
}
else
{
//MessageBox.Show("Can not find product id from " + productUrl);
}
//title
productInfo.title = "N/A";
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
//<div class="zg_title"><a href="http://www.amazon.com/Hamilton-Beach-25475-Breakfast-Sandwich/dp/B00BTIUYOO/ref=zg_bsnr_appliances_1/191-0874592-3518518">Hamilton Beach 25475 Breakfast Sandwich Maker, Gray</a></div>
XmlNode zgTitleNode = singleProductNode.SelectSingleNode(".//div[@class='zg_title']");
if (zgTitleNode != null)
{
productInfo.title = zgTitleNode.InnerText.Trim();
}
else
{
//special
//http://www.amazon.com/gp/new-releases/appliances/3741521/ref=zg_bsnr_nav_la_1_la
//7th item, contain nothing, only contain pic
}
//is top 100
//has top 100:
//http://www.amazon.com/gp/bestsellers/hi/ref=pd_dp_ts_hi_1
//<span class="zg_rankMeta"><span class="zg_arrowSprite zg_arrowUp"></span>2007 days in the top 100</span>
//normal no top 100:
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
//<span class="zg_rankMeta"></span>
XmlNode hasArrowSpriteNode = singleProductNode.SelectSingleNode(".//span[@class='zg_rankMeta']/span[@class]");
if (hasArrowSpriteNode != null)
{
productInfo.isTop100 = true;
}
else
{
productInfo.isTop100 = false;
}
//List Price, price, saving price and percentage
productInfo.listPrice = "N/A";
productInfo.salePrice = "N/A";
productInfo.savingPrice = "N/A";
productInfo.savingPercentage = "N/A";
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
//<p class="priceBlock"><strong>List Price: </strong> <span class="listprice">$65.00</span> </p><p class="priceBlock"><strong>Price: </strong> <span class="price"><b>$34.95</b></span> </p><p class="priceBlock"><strong>You Save: </strong> <span class="price">$30.05 (46%)</span></p>
//XmlNode listPriceNode = singleProductNode.SelectSingleNode(".//p[@class='priceBlock']/span[@class='listprice']");
//now html change to:
//<div class="zg_itemPriceBlock_compact">
//<div class="zg_price">
// <span class="listprice"></span>
// <strong class="price">$24.99</strong>
// <br />
//</div>
//<div class="zg_usedPrice">
// <a href="http://www.amazon.com/gp/offer-listing/B00CB38TUC/ref=zg_bsnr_12896361_price/181-1310935-2535815?ie=UTF8&condition=new">3 new</a> from
// <span class="price">$17.91</span>
//</div>
//</div>
XmlNode listPriceNode = singleProductNode.SelectSingleNode(".//div[@class='zg_price']/strong[@class='price']");
if (listPriceNode != null)
{
productInfo.listPrice = listPriceNode.InnerText;
}
//XmlNodeList priceNodeList = singleProductNode.SelectNodes(".//p[@class='priceBlock']/span[@class='price']");
//if (priceNodeList.Count > 0)
//{
// foreach (XmlNode curPriceNode in priceNodeList)
// {
// XmlNode parentNode = curPriceNode.ParentNode;
// if (parentNode.InnerXml.Contains("Price: "))
// {
// //<p class="priceBlock"><strong>Price: </strong> <span class="price"><b>$29.00</b></span>
// productInfo.salePrice = curPriceNode.InnerText;//$29.00
// }
// else if (parentNode.InnerXml.Contains("You Save:"))
// {
// //<p class="priceBlock"><strong>You Save: </strong> <span class="price">$30.05 (46%)</span></p>
// string savingTxt = curPriceNode.InnerText;
// string[] priceAndPercent = savingTxt.Split(' ');
// productInfo.savingPrice = priceAndPercent[0];
// if (priceAndPercent.Length > 1)
// {
// productInfo.savingPercentage = priceAndPercent[1].Replace("(", "").Replace(")", ""); ;
// }
// else
// {
// //some only contain price, no saving percentage
// //"<strong>You Save: </strong> <span class=\"price\">$0.04</span>"
// }
// }
// else
// {
// //tmp omit :
// //12 used & new from $25.00
// //in
// //<p class="priceBlock"><a href="http://www.amazon.com/gp/offer-listing/B00ARQVM5O/ref=zg_bsnr_appliances_price/191-0874592-3518518?ie=UTF8&condition=all">12 used & new</a> from <span class="price">$25.00</span>
// //from http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
// }
// }
//}
XmlNode usedPriceNode = singleProductNode.SelectSingleNode(".//div[@class='zg_usedPrice']/span[@class='price']");
if (usedPriceNode != null)
{
productInfo.salePrice = usedPriceNode.InnerText;
}
//rating and reviews
productInfo.rating = "N/A";
productInfo.reviews = "N/A";
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
//<span class="crAvgStars" style="white-space:no-wrap;"><span class="asinReviewsSummary acr-popover" name="B00BTIUYOO" ref="zg_bsnr_appliances_cm_cr_acr_pop_" > <a ......" ><span class="swSprite s_star_4_0 " title="4.0 out of 5 stars" ><span>4.0 out of 5 stars</span></span> </a> <span class="histogramButton" style="margin-left:-3px">......</span></span>(<a href="http://........ie=UTF8&showViewpoints=1" >14</a>)</span>
XmlNode avgStarsNode = singleProductNode.SelectSingleNode(".//span[@class='crAvgStars']");
if (avgStarsNode != null)
{
//rating
string productRating = "";
//<span class="swSprite s_star_4_0 " title="4.0 out of 5 stars" >
if (crifanLib.extractSingleStr(@"<span class=""swSprite.+?"" title=""([\d\.]+) out of 5 stars""",
avgStarsNode.InnerXml,
out productRating))
{
productInfo.rating = productRating;
}
else
{
MessageBox.Show("Can not find rating from" + avgStarsNode.InnerXml);
}
//reviews
XmlNode reviewsANode = avgStarsNode.SelectSingleNode("./a[@href]");
if (reviewsANode != null)
{
productInfo.reviews = reviewsANode.InnerText;
}
}
saveEachProduct(productInfo);
}
//void processSinglePageCategoryHtml(category.categoryItem curSelCategory, string singlePageHtml)
void processSinglePageCategoryHtml(string singlePageHtml)
{
string decodedHtml = HttpUtility.HtmlDecode(singlePageHtml);
XmlDocument xmlDoc = htmlToXmlDoc(decodedHtml);
//find title==category first
//<h1 id="zg_listTitle">Hot New Releases in <span class="category">Appliances</span></h1>
XmlNode listTitleNode = xmlDoc.SelectSingleNode("//h1[@id='zg_listTitle']/span[@class='category']");
string categoryName = listTitleNode.InnerText;
//find products info
//<div class="zg_itemRow">
//XmlNodeList zgItemRowNodeList = xmlDoc.SelectNodes("//div[@class='zg_itemRow']");
//now html change to:
//<div class="zg_itemWrapper" style="height:300px">
XmlNodeList zgItemRowNodeList = xmlDoc.SelectNodes("//div[@class='zg_itemWrapper']");
foreach (XmlNode singleProductNode in zgItemRowNodeList)
{
//processEachProductNode(curSelCategory, singleProductNode);
processEachProductNode(categoryName, singleProductNode);
}
}
//void processSubCategoryHtml(category.categoryItem curSelCategory, string subCategoryHtml)
void processSubCategoryHtml(string subCategoryHtml)
{
//string decodedHtml = HttpUtility.HtmlDecode(subCategoryHtml);
////<div class="zg_itemRow">
//XmlDocument xmlDoc = htmlToXmlDoc(decodedHtml);
//XmlNodeList zgItemRowNodeList = xmlDoc.SelectNodes("//div[@class='zg_itemRow']");
////find title==category first
////<h1 id="zg_listTitle">Hot New Releases in <span class="category">Appliances</span></h1>
//XmlNode listTitleNode = xmlDoc.SelectSingleNode("//h1[@id='zg_listTitle']/span[@class='category']");
//string categoryName = listTitleNode.InnerText;
//foreach (XmlNode singleProductNode in zgItemRowNodeList)
//{
// //processEachProductNode(curSelCategory, singleProductNode);
// processEachProductNode(categoryName, singleProductNode);
//}
processSinglePageCategoryHtml(subCategoryHtml);
//check if still has more page
//normal:
//http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_nav_0
//has more page:
//<div id='zg_paginationWrapper'>
//<ol class="zg_pagination">
//<li class="zg_page zg_selected" id="zg_page1">
// <a page="1" ajaxUrl="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_1/191-0874592-3518518?ie=UTF8&pg=1&ajax=1" href="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_1/191-0874592-3518518?ie=UTF8&pg=1">1-20</a></li><li class="zg_page " id="zg_page2">
//...
//<li class="zg_page " id="zg_page5">
// <a page="5" ajaxUrl="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_5/191-0874592-3518518?ie=UTF8&pg=5&ajax=1" href="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_5/191-0874592-3518518?ie=UTF8&pg=5">81-100</a></li>
//</ol>
//</div>
//speical:
//http://www.amazon.com/gp/new-releases/appliances/3741261/ref=zg_bsnr_nav_la_1_la
//no more page:
//<div id='zg_paginationWrapper'>
//<ol class="zg_pagination">
//<li class="zg_page zg_selected" id="zg_page1">
// <a page="1" ajaxUrl="http://www.amazon.com/gp/new-releases/appliances/3741261/ref=zg_bsnr_3741261_pg_1?ie=UTF8&pg=1&ajax=1" href="http://www.amazon.com/gp/new-releases/appliances/3741261/ref=zg_bsnr_3741261_pg_1?ie=UTF8&pg=1">1-5</a></li>
//</ol>
//</div>
//<ol class="zg_pagination">
//<li class="zg_page " id="zg_page2"><a page="2" ajaxUrl="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_2/191-0874592-3518518?ie=UTF8&pg=2&ajax=1" href="http://www.amazon.com/gp/new-releases/appliances/ref=zg_bsnr_appliances_pg_2/191-0874592-3518518?ie=UTF8&pg=2">21-40</a></li>
XmlDocument xmlDoc = htmlToXmlDoc(HttpUtility.HtmlDecode(subCategoryHtml));
XmlNodeList pageNodeList = xmlDoc.SelectNodes("//ol[@class='zg_pagination']/li[@class]");
if (pageNodeList.Count > 1)
{
//more than 1 page
for (int pageIdx = 1; pageIdx < pageNodeList.Count; pageIdx++)
{
XmlNode curPageNode = pageNodeList[pageIdx];
XmlNode ajaxUrlNode = curPageNode.SelectSingleNode(".//a[@href]");
string pageUrl = ajaxUrlNode.Attributes["href"].Value;
string singlePageHtml = crifanLib.getUrlRespHtml(pageUrl);
//processSinglePageCategoryHtml(curSelCategory, singlePageHtml);
processSinglePageCategoryHtml(singlePageHtml);
}
}
}
void clearSearchResult()
{
dgvProductInfo.Rows.Clear();
}
private void btnSearch_Click(object sender, EventArgs e)
{
category.categoryItem curSelCategory = getCurrentSelectedCategory();
if ((curSelCategory.Url != null) && (curSelCategory.Url != ""))
{
clearSearchResult();
string subCatRespHtml = crifanLib.getUrlRespHtml(curSelCategory.Url);
//processSubCategoryHtml(curSelCategory, subCatRespHtml);
processSubCategoryHtml(subCatRespHtml);
}
}
private void btnClearAll_Click(object sender, EventArgs e)
{
dgvProductInfo.Rows.Clear();
}
private string getSaveFolder()
{
string saveFolderPath = "";
//string saveFolderPath = System.Environment.CurrentDirectory;
//fbdSaveFolder.SelectedPath = System.Environment.CurrentDirectory;
DialogResult saveFolderResult = fbdSaveFolder.ShowDialog();
if (saveFolderResult == System.Windows.Forms.DialogResult.OK)
{
saveFolderPath = fbdSaveFolder.SelectedPath;
}
else if (saveFolderResult == System.Windows.Forms.DialogResult.Cancel)
{
saveFolderPath = "";
}
return saveFolderPath;
}
private void openFolderAndSelectFile(string fullFilename)
{
System.Diagnostics.Process.Start("Explorer.exe", "/select," + fullFilename);
}
private void btnExportToCsv_Click(object sender, EventArgs e)
{
string saveFolderPath = getSaveFolder();
if ((saveFolderPath == null) || (saveFolderPath == ""))
{
return;
}
//settings
//string delimiter = "|";
string delimiter = ",";
string outputFilename = txbExportFilename.Text + ".csv";
string fullFilename = Path.Combine(saveFolderPath, outputFilename);
StreamWriter csvStreamWriter = new StreamWriter(fullFilename, false, System.Text.Encoding.UTF8);
//output header data
string strHeader = "";
for (int i = 0; i < dgvProductInfo.Columns.Count; i++)
{
strHeader += dgvProductInfo.Columns[i].HeaderText + delimiter;
}
csvStreamWriter.WriteLine(strHeader);
//output rows data
for (int j = 0; j < dgvProductInfo.Rows.Count; j++)
{
string strRowValue = "";
for (int k = 0; k < dgvProductInfo.Columns.Count; k++)
{
strRowValue += dgvProductInfo.Rows[j].Cells[k].Value + delimiter;
}
csvStreamWriter.WriteLine(strRowValue);
}
csvStreamWriter.Close();
//after save file
openFolderAndSelectFile(fullFilename);
}
private void btnExportToExcel_Click(object sender, EventArgs e)
{
string saveFolderPath = getSaveFolder();
if ((saveFolderPath == null) || (saveFolderPath == ""))
{
return;
}
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
int i = 0;
int j = 0;
//save header
for (i = 0; i <= dgvProductInfo.ColumnCount - 1; i++)
{
xlWorkSheet.Cells[0 + 1, i + 1] = dgvProductInfo.Columns[i].HeaderText;
}
//save cells
for (i = 0; i <= dgvProductInfo.RowCount - 1; i++)
{
for (j = 0; j <= dgvProductInfo.ColumnCount - 1; j++)
{
DataGridViewCell cell = dgvProductInfo[j, i];
xlWorkSheet.Cells[i + 2, j + 1] = cell.Value;
}
}
//formatting
//header to bold
Range headerRow = xlWorkSheet.get_Range("1:1", System.Type.Missing);
headerRow.Font.Bold = true;
string outputFilename = txbExportFilename.Text + ".xls";
string fullFilename = Path.Combine(saveFolderPath, outputFilename);
//xlWorkBook.SaveAs(fullFilename, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.SaveAs(fullFilename, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, XlSaveConflictResolution.xlLocalSessionChanges, misValue, misValue, misValue, misValue);
//auto adjust column width (according to content)
Range allColumn = xlWorkSheet.Columns;
allColumn.AutoFit();
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
openFolderAndSelectFile(fullFilename);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}
【总结】