// parameters: // lStartIndex 调用前已经做过的事项数。为了准确显示 Progress // return: // -2 获得书目摘要的权限不够 // -1 出错 // 0 用户中断 // 1 完成 public int FillBiblioSummaryColumn( LibraryChannel channel, List<ListViewItem> items, long lStartIndex, bool bDisplayMessage, bool bPrepareLoop, out string strError) { strError = ""; // int nRet = 0; if (bPrepareLoop) { stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在填充书目摘要 ..."); stop.BeginLoop(); } try { stop.SetProgressRange(0, items.Count); List<string> biblio_recpaths = new List<string>(); // 尺寸可能比 items 数组小,没有包含里面不具有 parent id 列的事项 // List<int> colindex_list = new List<int>(); // 存储每个 item 对应的 parent id colindex。数组大小等于 items 数组大小 foreach (ListViewItem item in items) { string strBiblioRecPath = ListViewUtil.GetItemText(item, COLUMN_RECPATH); biblio_recpaths.Add(strBiblioRecPath); } CacheableBiblioLoader loader = new CacheableBiblioLoader(); loader.Channel = channel; // this.Channel; loader.Stop = this.stop; loader.Format = "summary"; loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; loader.RecPaths = biblio_recpaths; var enumerator = loader.GetEnumerator(); int i = 0; foreach (ListViewItem item in items) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return 0; } string strRecPath = ListViewUtil.GetItemText(item, 0); if (stop != null && bDisplayMessage == true) { stop.SetMessage("正在刷新浏览行 " + strRecPath + " 的书目摘要 ..."); stop.SetProgressValue(lStartIndex + i); } try { bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 strError = "error 1"; return -1; } } catch (ChannelException ex) { strError = ex.Message; if (ex.ErrorCode == ErrorCode.AccessDenied) return -2; return -1; } BiblioItem biblio = (BiblioItem)enumerator.Current; // Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); ListViewUtil.ChangeItemText(item, 1, biblio.Content); i++; stop.SetProgressValue(i); } return 1; } catch (Exception ex) { strError = "填充书目摘要的过程出现异常: " + ExceptionUtil.GetAutoText(ex); return -1; } finally { if (bPrepareLoop) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); } } }
// parameters: // lStartIndex 调用前已经做过的事项数。为了准确显示 Progress // return: // -2 获得书目摘要的权限不够 // -1 出错 // 0 用户中断 // 1 完成 internal int _fillBiblioSummaryColumn(List<ListViewItem> items, long lStartIndex, bool bDisplayMessage, bool bAutoSearch, out string strError) { strError = ""; int nRet = 0; if (m_bBiblioSummaryColumn == false) return 0; Debug.Assert(this.DbType == "item" || this.DbType == "order" || this.DbType == "issue" || this.DbType == "comment" || this.DbType == "arrive", ""); List<string> biblio_recpaths = new List<string>(); // 尺寸可能比 items 数组小,没有包含里面不具有 parent id 列的事项 List<int> colindex_list = new List<int>(); // 存储每个 item 对应的 parent id colindex。数组大小等于 items 数组大小 foreach (ListViewItem item in items) { #if NO string strRecPath = ListViewUtil.GetItemText(item, 0); // 根据记录路径获得数据库名 string strItemDbName = Global.GetDbName(strRecPath); // 根据数据库名获得 parent id 列号 int nCol = -1; object o = m_tableSummaryColIndex[strItemDbName]; if (o == null) { ColumnPropertyCollection temp = this.MainForm.GetBrowseColumnProperties(strItemDbName); nCol = temp.FindColumnByType("parent_id"); if (nCol == -1) { colindex_list.Add(-1); continue; // 这个实体库没有 parent id 列 } nCol += 2; if (this.m_bFirstColumnIsKey == true) nCol++; // 2013/11/12 m_tableSummaryColIndex[strItemDbName] = nCol; // 储存起来 } else nCol = (int)o; Debug.Assert(nCol > 0, ""); colindex_list.Add(nCol); // 获得 parent id string strText = ListViewUtil.GetItemText(item, nCol); string strBiblioRecPath = ""; // 看看是否已经是路径 ? if (strText.IndexOf("/") == -1) { // 获得对应的书目库名 strBiblioRecPath = this.MainForm.GetBiblioDbNameFromItemDbName(this.DbType, strItemDbName); if (string.IsNullOrEmpty(strBiblioRecPath) == true) { strError = "数据库名 '" + strItemDbName + "' 没有找到对应的书目库名"; return -1; } strBiblioRecPath = strBiblioRecPath + "/" + strText; ListViewUtil.ChangeItemText(item, nCol, strBiblioRecPath); } else strBiblioRecPath = strText; #endif int nCol = -1; string strBiblioRecPath = ""; // 获得事项所从属的书目记录的路径 // return: // -1 出错 // 0 相关数据库没有配置 parent id 浏览列 // 1 找到 nRet = GetBiblioRecPath(item, bAutoSearch, // true 如果遇到没有 parent id 列的时候速度较慢 out nCol, out strBiblioRecPath, out strError); if (nRet == -1) return -1; if (nRet == 0) { colindex_list.Add(-1); continue; } if (string.IsNullOrEmpty(strBiblioRecPath) == false && nCol == -1) colindex_list.Add(0); else colindex_list.Add(nCol); biblio_recpaths.Add(strBiblioRecPath); } CacheableBiblioLoader loader = new CacheableBiblioLoader(); loader.Channel = this.Channel; loader.Stop = this.stop; loader.Format = "summary"; loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; loader.RecPaths = biblio_recpaths; var enumerator = loader.GetEnumerator(); int i = 0; foreach (ListViewItem item in items) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return 0; } string strRecPath = ListViewUtil.GetItemText(item, 0); if (stop != null && bDisplayMessage == true) { stop.SetMessage("正在刷新浏览行 " + strRecPath + " 的书目摘要 ..."); stop.SetProgressValue(lStartIndex + i); } int nCol = colindex_list[i]; if (nCol == -1) { ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, ""); ClearOneChange(item, true); // 清除内存中的修改 i++; continue; } try { bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 strError = "error 1"; return -1; } } catch (ChannelException ex) { strError = ex.Message; if (ex.ErrorCode == ErrorCode.AccessDenied) return -2; return -1; } BiblioItem biblio = (BiblioItem)enumerator.Current; // Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, biblio.Content); ClearOneChange(item, true); // 清除内存中的修改 i++; } return 1; }
// parameters: // lStartIndex 调用前已经做过的事项数。为了准确显示 Progress // return: // -2 获得书目摘要的权限不够 // -1 出错 // 0 用户中断 // 1 完成 internal int _fillBiblioSummaryColumn(List <ListViewItem> items, long lStartIndex, bool bDisplayMessage, bool bAutoSearch, out string strError) { strError = ""; int nRet = 0; if (m_bBiblioSummaryColumn == false) { return(0); } Debug.Assert(this.DbType == "item" || this.DbType == "order" || this.DbType == "issue" || this.DbType == "comment" || this.DbType == "arrive", ""); List <string> biblio_recpaths = new List <string>(); // 尺寸可能比 items 数组小,没有包含里面不具有 parent id 列的事项 List <int> colindex_list = new List <int>(); // 存储每个 item 对应的 parent id colindex。数组大小等于 items 数组大小 foreach (ListViewItem item in items) { #if NO string strRecPath = ListViewUtil.GetItemText(item, 0); // 根据记录路径获得数据库名 string strItemDbName = Global.GetDbName(strRecPath); // 根据数据库名获得 parent id 列号 int nCol = -1; object o = m_tableSummaryColIndex[strItemDbName]; if (o == null) { ColumnPropertyCollection temp = this.MainForm.GetBrowseColumnProperties(strItemDbName); nCol = temp.FindColumnByType("parent_id"); if (nCol == -1) { colindex_list.Add(-1); continue; // 这个实体库没有 parent id 列 } nCol += 2; if (this.m_bFirstColumnIsKey == true) { nCol++; // 2013/11/12 } m_tableSummaryColIndex[strItemDbName] = nCol; // 储存起来 } else { nCol = (int)o; } Debug.Assert(nCol > 0, ""); colindex_list.Add(nCol); // 获得 parent id string strText = ListViewUtil.GetItemText(item, nCol); string strBiblioRecPath = ""; // 看看是否已经是路径 ? if (strText.IndexOf("/") == -1) { // 获得对应的书目库名 strBiblioRecPath = this.MainForm.GetBiblioDbNameFromItemDbName(this.DbType, strItemDbName); if (string.IsNullOrEmpty(strBiblioRecPath) == true) { strError = "数据库名 '" + strItemDbName + "' 没有找到对应的书目库名"; return(-1); } strBiblioRecPath = strBiblioRecPath + "/" + strText; ListViewUtil.ChangeItemText(item, nCol, strBiblioRecPath); } else { strBiblioRecPath = strText; } #endif int nCol = -1; string strBiblioRecPath = ""; // 获得事项所从属的书目记录的路径 // return: // -1 出错 // 0 相关数据库没有配置 parent id 浏览列 // 1 找到 nRet = GetBiblioRecPath(item, bAutoSearch, // true 如果遇到没有 parent id 列的时候速度较慢 out nCol, out strBiblioRecPath, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { colindex_list.Add(-1); continue; } if (string.IsNullOrEmpty(strBiblioRecPath) == false && nCol == -1) { colindex_list.Add(0); } else { colindex_list.Add(nCol); } biblio_recpaths.Add(strBiblioRecPath); } CacheableBiblioLoader loader = new CacheableBiblioLoader(); loader.Channel = this.Channel; loader.Stop = this.stop; loader.Format = "summary"; loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; loader.RecPaths = biblio_recpaths; var enumerator = loader.GetEnumerator(); int i = 0; foreach (ListViewItem item in items) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return(0); } string strRecPath = ListViewUtil.GetItemText(item, 0); if (stop != null && bDisplayMessage == true) { stop.SetMessage("正在刷新浏览行 " + strRecPath + " 的书目摘要 ..."); stop.SetProgressValue(lStartIndex + i); } int nCol = colindex_list[i]; if (nCol == -1) { ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, ""); ClearOneChange(item, true); // 清除内存中的修改 i++; continue; } try { bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 strError = "error 1"; return(-1); } } catch (ChannelException ex) { strError = ex.Message; if (ex.ErrorCode == ErrorCode.AccessDenied) { return(-2); } return(-1); } BiblioItem biblio = (BiblioItem)enumerator.Current; // Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, biblio.Content); ClearOneChange(item, true); // 清除内存中的修改 i++; } return(1); }
// parameters: // bAdvanceXml 是否为 AdvanceXml 情况 static void OutputBorrowHistory( IXLWorksheet sheet, XmlDocument reader_dom, ChargingHistoryLoader history_loader, CacheableBiblioLoader summary_loader, // Delegate_GetBiblioSummary procGetBiblioSummary, ref int nRowIndex, ref List<int> column_max_chars) { int nStartRow = nRowIndex; OutputTitleLine(sheet, ref nRowIndex, "--- 借阅历史 --- " + history_loader.GetCount(), XLColor.DarkGreen, 2, 7); List<IXLCell> cells = new List<IXLCell>(); // 册信息若干行的标题 { List<string> titles = new List<string>(); titles.Add("序号"); titles.Add("册条码号"); titles.Add("书目摘要"); titles.Add("借阅时间"); titles.Add("期限"); titles.Add("借阅操作者"); titles.Add("还书时间"); titles.Add("还书操作者"); int nColIndex = 2; foreach (string s in titles) { IXLCell cell = sheet.Cell(nRowIndex, nColIndex).SetValue(s); cell.Style.Alignment.WrapText = true; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; cell.Style.Font.Bold = true; cell.Style.Font.FontColor = XLColor.DarkGray; //cell.Style.Font.FontName = strFontName; //cell.Style.Alignment.Horizontal = alignments[nColIndex - 1]; nColIndex++; cells.Add(cell); } nRowIndex++; } List<string> item_barcodes = new List<string>(); List<Point> points = new List<Point>(); int nItemIndex = 0; foreach (ChargingItemWrapper wrapper in history_loader) { ChargingItem item = wrapper.Item; ChargingItem rel = wrapper.RelatedItem; string strItemBarcode = item.ItemBarcode; string strBorrowDate = rel == null ? "" : rel.OperTime; string strBorrowPeriod = GetDisplayTimePeriodString(rel == null ? "" : rel.Period); string strReturnDate = item.OperTime; //string strRecPath = borrow.GetAttribute("recPath"); //string strIsOverdue = borrow.GetAttribute("isOverdue"); //bool bIsOverdue = DomUtil.IsBooleanTrue(strIsOverdue, false); //string strOverdueInfo = borrow.GetAttribute("overdueInfo1"); string strSummary = ""; #if NO if (string.IsNullOrEmpty(strItemBarcode) == false && string.IsNullOrEmpty(strSummary) == true) { string strError = ""; int nRet = procGetBiblioSummary(strItemBarcode, "", // strConfirmItemRecPath, false, out strSummary, out strError); if (nRet == -1) strSummary = strError; } #endif item_barcodes.Add("@itemBarcode:" + strItemBarcode); List<string> cols = new List<string>(); cols.Add((nItemIndex + 1).ToString()); cols.Add(strItemBarcode); cols.Add(strSummary); cols.Add(strBorrowDate); cols.Add(strBorrowPeriod); cols.Add(rel == null ? "" : rel.Operator); cols.Add(strReturnDate); cols.Add(item.Operator); int nColIndex = 2; points.Add(new Point(nColIndex + 2, nRowIndex)); foreach (string s in cols) { // 统计最大字符数 SetMaxChars(ref column_max_chars, nColIndex - 1, GetCharWidth(s)); IXLCell cell = null; if (nColIndex == 2) { cell = sheet.Cell(nRowIndex, nColIndex).SetValue(nItemIndex + 1); cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; } else cell = sheet.Cell(nRowIndex, nColIndex).SetValue(s); cell.Style.Alignment.WrapText = true; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; //cell.Style.Font.FontName = strFontName; //cell.Style.Alignment.Horizontal = alignments[nColIndex - 1]; nColIndex++; cells.Add(cell); } #if NO // 超期的行为黄色背景 if (bIsOverdue) { var line = sheet.Range(nRowIndex, 2, nRowIndex, 2 + cols.Count - 1); line.Style.Fill.BackgroundColor = XLColor.Yellow; } #endif nItemIndex++; nRowIndex++; } // 加入书目摘要 summary_loader.RecPaths = item_barcodes; int i = 0; foreach (BiblioItem biblio in summary_loader) { Point point = points[i]; int nColIndex = point.X; // 统计最大字符数 SetMaxChars(ref column_max_chars, nColIndex - 1, GetCharWidth(biblio.Content)); IXLCell cell = null; cell = sheet.Cell(point.Y, nColIndex).SetValue(biblio.Content); cell.Style.Alignment.WrapText = true; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; i++; } // 册信息标题下的虚线 var rngData = sheet.Range(cells[0], cells[cells.Count - 1]); rngData.FirstRow().Style.Border.TopBorder = XLBorderStyleValues.Dotted; sheet.Rows(nStartRow + 1, nRowIndex - 1).Group(); }
// return: // -1 出错 // 0 用户中断 // 1 成功 public int CreateReaderDetailExcelFile(List<string> reader_barcodes, bool bLaunchExcel, out string strError) { strError = ""; //int nRet = 0; ExportPatronExcelDialog dlg = new ExportPatronExcelDialog(); MainForm.SetControlFont(dlg, this.Font, false); dlg.OverwritePrompt = true; dlg.UiState = this.MainForm.AppInfo.GetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", ""); this.MainForm.AppInfo.LinkFormState(dlg, "ReaderSearchForm_ExportPatronExcelDialog_uiState_state"); dlg.ShowDialog(this); this.MainForm.AppInfo.SetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", dlg.UiState); if (dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) { strError = "放弃操作"; return 0; } string strTimeRange = ""; try { strTimeRange = GetTimeRange(dlg.ChargingHistoryDateRange); } catch (Exception ex) { strError = "日期范围字符串 '" + dlg.ChargingHistoryDateRange + "' 格式不合法: " + ex.Message; return -1; } XLWorkbook doc = null; try { doc = new XLWorkbook(XLEventTracking.Disabled); File.Delete(dlg.FileName); } catch (Exception ex) { strError = "ReaderSearchForm new XLWorkbook() {39D0940F-33FF-4A10-8F61-1FFFEEBFF4D0} exception: " + ExceptionUtil.GetAutoText(ex); return -1; } IXLWorksheet sheet = null; sheet = doc.Worksheets.Add("表格"); // 每个列的最大字符数 List<int> column_max_chars = new List<int>(); // TODO: 表的标题,创建时间 int nRowIndex = 3; // 空出前两行 //int nColIndex = 1; int nReaderIndex = 0; try { // return: // -1 出错。包括用户中断的情况 // >=0 实际处理的读者记录数 int nRet = this.ProcessPatrons( reader_barcodes, "advancexml,advancexml_borrow_bibliosummary,advancexml_overdue_bibliosummary", // advancexml_history_bibliosummary (strRecPath, dom, timestamp) => { this.ShowMessage("正在处理读者记录 " + strRecPath); string strBarcode = DomUtil.GetElementText(dom.DocumentElement, "barcode"); // if (dlg.ExportReaderInfo) { OutputReaderInfo(sheet, dom, nReaderIndex, ref nRowIndex, ref column_max_chars); } // 输出在借册表格 if (dlg.ExportBorrowInfo) { OutputBorrows(sheet, dom, this.MainForm.GetBiblioSummary, true, ref nRowIndex, ref column_max_chars); } // 输出违约金表格 if (dlg.ExportOverdueInfo) { OutputOverdues(sheet, dom, this.MainForm.GetBiblioSummary, ref nRowIndex, ref column_max_chars); } if (dlg.ExportChargingHistory) { try { ChargingHistoryLoader history_loader = new ChargingHistoryLoader(); history_loader.Channel = this.Channel; history_loader.Stop = this.stop; history_loader.PatronBarcode = strBarcode; history_loader.TimeRange = strTimeRange; history_loader.Actions = "return,lost"; history_loader.Order = "descending"; CacheableBiblioLoader summary_loader = new CacheableBiblioLoader(); summary_loader.Channel = this.Channel; summary_loader.Stop = this.stop; summary_loader.Format = "summary"; summary_loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; // summary_loader.RecPaths = biblio_recpaths; // 输出借阅历史表格 // 可能会抛出异常,例如权限不够 OutputBorrowHistory(sheet, dom, history_loader, // this.MainForm.GetBiblioSummary, summary_loader, ref nRowIndex, ref column_max_chars); } catch (Exception ex) { string strErrorText = "输出借阅历史时出现异常: " + ex.Message; throw new Exception(strErrorText); } } nRowIndex++; // 读者之间的空行 nReaderIndex++; return true; }, out strError); if (nRet == -1) return -1; { if (stop != null) stop.SetMessage("正在调整列宽度 ..."); Application.DoEvents(); //double char_width = GetAverageCharPixelWidth(list); // 字符数太多的列不要做 width auto adjust foreach (IXLColumn column in sheet.Columns()) { int MAX_CHARS = 50; // 60 int nIndex = column.FirstCell().Address.ColumnNumber - 1; if (nIndex >= column_max_chars.Count) break; int nChars = column_max_chars[nIndex]; if (nIndex == 1) { column.Width = 10; continue; } if (nIndex == 3) MAX_CHARS = 50; else MAX_CHARS = 24; if (nChars < MAX_CHARS) column.AdjustToContents(); else column.Width = Math.Min(MAX_CHARS, nChars); //else // column.Width = (double)list.Columns[i].Width / char_width; // Math.Min(MAX_CHARS, nChars); } } this.ShowMessage("共导出读者记录 " + nReaderIndex + " 个", "green", true); } catch (Exception ex) { strError = "CreateDetailExcelFile() 出现异常: " + ExceptionUtil.GetExceptionText(ex); return -1; } finally { if (stop != null) stop.SetMessage(""); if (doc != null) { doc.SaveAs(dlg.FileName); doc.Dispose(); } if (bLaunchExcel) { try { System.Diagnostics.Process.Start(dlg.FileName); } catch { } } } // TODO: sheet 可以按照单位来区分。例如按照班级 return 1; }
// return: // -1 出错 // 0 用户中断 // 1 成功 public int CreateReaderDetailExcelFile(List<string> reader_barcodes, bool bLaunchExcel, out string strError) { strError = ""; //int nRet = 0; ExportPatronExcelDialog dlg = new ExportPatronExcelDialog(); MainForm.SetControlFont(dlg, this.Font, false); dlg.OverwritePrompt = true; dlg.UiState = this.MainForm.AppInfo.GetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", ""); this.MainForm.AppInfo.LinkFormState(dlg, "ReaderSearchForm_ExportPatronExcelDialog_uiState_state"); dlg.ShowDialog(this); this.MainForm.AppInfo.SetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", dlg.UiState); if (dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) { strError = "放弃操作"; return 0; } #if NO // 提醒覆盖文件 if (File.Exists(dlg.FileName) == true) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已经存在。继续操作将覆盖此文件。\r\n\r\n请问是否要覆盖此文件? (OK 覆盖;Cancel 放弃操作)", "ReaderSearchForm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Cancel) { strError = "放弃操作"; return 0; } } #endif string strTimeRange = ""; try { strTimeRange = GetTimeRange(dlg.ChargingHistoryDateRange); } catch (Exception ex) { strError = "日期范围字符串 '" + dlg.ChargingHistoryDateRange + "' 格式不合法: " + ex.Message; return -1; } #if NO // 询问文件名 SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "请指定要输出的 Excel 文件名"; dlg.CreatePrompt = false; dlg.OverwritePrompt = true; // dlg.FileName = this.ExportExcelFilename; // dlg.InitialDirectory = Environment.CurrentDirectory; dlg.Filter = "Excel 文件 (*.xlsx)|*.xlsx|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) return 0; #endif XLWorkbook doc = null; try { doc = new XLWorkbook(XLEventTracking.Disabled); File.Delete(dlg.FileName); } catch (Exception ex) { strError = "ReaderSearchForm new XLWorkbook() {39D0940F-33FF-4A10-8F61-1FFFEEBFF4D0} exception: " + ExceptionUtil.GetAutoText(ex); return -1; } IXLWorksheet sheet = null; sheet = doc.Worksheets.Add("表格"); // TODO: sheet 可以按照单位来区分。例如按照班级 stop.Style = StopStyle.EnableHalfStop; stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("导出读者详情 ..."); stop.BeginLoop(); EnableControls(false); this.listView_records.Enabled = false; try { if (stop != null) stop.SetProgressRange(0, reader_barcodes.Count); // 每个列的最大字符数 List<int> column_max_chars = new List<int>(); // TODO: 表的标题,创建时间 int nRowIndex = 3; // 空出前两行 //int nColIndex = 1; int nReaderIndex = 0; foreach (string strBarcode in reader_barcodes) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return 0; } if (string.IsNullOrEmpty(strBarcode) == true) continue; // 获得读者记录 byte[] baTimestamp = null; string strOutputRecPath = ""; stop.SetMessage("正在处理读者记录 " + strBarcode + " ..."); string[] results = null; long lRet = Channel.GetReaderInfo( stop, strBarcode, "advancexml,advancexml_borrow_bibliosummary,advancexml_overdue_bibliosummary", // advancexml_history_bibliosummary out results, out strOutputRecPath, out baTimestamp, out strError); if (lRet == -1) return -1; if (lRet == 0) return -1; if (lRet > 1) // 不可能发生吧? { strError = "读者证条码号 " + strBarcode + " 命中记录 " + lRet.ToString() + " 条,放弃装入读者记录。\r\n\r\n注意这是一个严重错误,请系统管理员尽快排除。"; return -1; } if (results == null || results.Length < 1) { strError = "返回的results不正常。"; return -1; } string strXml = results[0]; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "装载读者记录 XML 到 DOM 时发生错误: " + ex.Message; return -1; } // if (dlg.ExportReaderInfo) { OutputReaderInfo(sheet, dom, nReaderIndex, ref nRowIndex, ref column_max_chars); } // 输出在借册表格 if (dlg.ExportBorrowInfo) { OutputBorrows(sheet, dom, this.MainForm.GetBiblioSummary, true, ref nRowIndex, ref column_max_chars); } // 输出违约金表格 if (dlg.ExportOverdueInfo) { OutputOverdues(sheet, dom, this.MainForm.GetBiblioSummary, ref nRowIndex, ref column_max_chars); } if (dlg.ExportChargingHistory) { try { ChargingHistoryLoader history_loader = new ChargingHistoryLoader(); history_loader.Channel = this.Channel; history_loader.Stop = this.stop; history_loader.PatronBarcode = strBarcode; history_loader.TimeRange = strTimeRange; history_loader.Actions = "return,lost"; history_loader.Order = "descending"; CacheableBiblioLoader summary_loader = new CacheableBiblioLoader(); summary_loader.Channel = this.Channel; summary_loader.Stop = this.stop; summary_loader.Format = "summary"; summary_loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; // summary_loader.RecPaths = biblio_recpaths; // 输出借阅历史表格 OutputBorrowHistory(sheet, dom, history_loader, // this.MainForm.GetBiblioSummary, summary_loader, ref nRowIndex, ref column_max_chars); } catch (Exception ex) { strError = "输出借阅历史时出现异常: " + ex.Message; return -1; } } nRowIndex++; // 读者之间的空行 nReaderIndex++; if (stop != null) stop.SetProgressValue(nReaderIndex); } { if (stop != null) stop.SetMessage("正在调整列宽度 ..."); Application.DoEvents(); //double char_width = GetAverageCharPixelWidth(list); // 字符数太多的列不要做 width auto adjust foreach (IXLColumn column in sheet.Columns()) { int MAX_CHARS = 50; // 60 int nIndex = column.FirstCell().Address.ColumnNumber - 1; if (nIndex >= column_max_chars.Count) break; int nChars = column_max_chars[nIndex]; if (nIndex == 1) { column.Width = 10; continue; } if (nIndex == 3) MAX_CHARS = 50; else MAX_CHARS = 24; if (nChars < MAX_CHARS) column.AdjustToContents(); else column.Width = Math.Min(MAX_CHARS, nChars); //else // column.Width = (double)list.Columns[i].Width / char_width; // Math.Min(MAX_CHARS, nChars); } } } finally { EnableControls(true); this.listView_records.Enabled = true; stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); stop.Style = StopStyle.None; if (doc != null) { doc.SaveAs(dlg.FileName); doc.Dispose(); } if (bLaunchExcel) { try { System.Diagnostics.Process.Start(dlg.FileName); } catch { } } } return 1; }
// 创建读者详情 Excel 文件。这是便于被外部调用的版本,只需要提供读者 XML 记录即可 // return: // -1 出错 // 0 用户中断 // 1 成功 public static int CreateReaderDetailExcelFile(List<string> xmls, Delegate_GetBiblioSummary procGetBiblioSummary, Stop stop, bool bAdvanceXml, bool bLaunchExcel, out string strError) { strError = ""; //int nRet = 0; ExportPatronExcelDialog dlg = new ExportPatronExcelDialog(); MainForm.SetControlFont(dlg, Program.MainForm.Font, false); dlg.UiState = Program.MainForm.AppInfo.GetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", ""); Program.MainForm.AppInfo.LinkFormState(dlg, "ReaderSearchForm_ExportPatronExcelDialog_uiState_state"); dlg.ShowDialog(Program.MainForm); Program.MainForm.AppInfo.SetString( "ReaderSearchForm", "ExportPatronExcelDialog_uiState", dlg.UiState); if (dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) { strError = "放弃操作"; return 0; } string strTimeRange = ""; try { strTimeRange = GetTimeRange(dlg.ChargingHistoryDateRange); } catch (Exception ex) { strError = "日期范围字符串 '" + dlg.ChargingHistoryDateRange + "' 格式不合法: " + ex.Message; return -1; } #if NO // 询问文件名 SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "请指定要输出的 Excel 文件名"; dlg.CreatePrompt = false; dlg.OverwritePrompt = true; // dlg.FileName = this.ExportExcelFilename; // dlg.InitialDirectory = Environment.CurrentDirectory; dlg.Filter = "Excel 文件 (*.xlsx)|*.xlsx|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) return 0; #endif XLWorkbook doc = null; try { doc = new XLWorkbook(XLEventTracking.Disabled); File.Delete(dlg.FileName); } catch (Exception ex) { strError = "ReaderSearchForm new XLWorkbook() {0BD1CB34-DF8A-4DDB-B884-8A9CF830D7C7} exception: " + ExceptionUtil.GetAutoText(ex); return -1; } IXLWorksheet sheet = null; sheet = doc.Worksheets.Add("表格"); try { if (stop != null) stop.SetProgressRange(0, xmls.Count); // 每个列的最大字符数 List<int> column_max_chars = new List<int>(); // TODO: 表的标题,创建时间 int nRowIndex = 3; // 空出前两行 //int nColIndex = 1; int nReaderIndex = 0; foreach (string strXml in xmls) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) return 0; if (string.IsNullOrEmpty(strXml) == true) continue; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "装载读者记录 XML 到 DOM 时发生错误: " + ex.Message; return -1; } string strBarcode = DomUtil.GetElementText(dom.DocumentElement, "barcode"); // if (dlg.ExportReaderInfo) { OutputReaderInfo(sheet, dom, nReaderIndex, ref nRowIndex, ref column_max_chars); } // 输出在借册表格 if (dlg.ExportBorrowInfo) { OutputBorrows(sheet, dom, procGetBiblioSummary, bAdvanceXml, ref nRowIndex, ref column_max_chars); } // 输出违约金表格 if (dlg.ExportOverdueInfo) { OutputOverdues(sheet, dom, procGetBiblioSummary, ref nRowIndex, ref column_max_chars); } if (dlg.ExportChargingHistory) { LibraryChannel channel = Program.MainForm.GetChannel(); try { ChargingHistoryLoader history_loader = new ChargingHistoryLoader(); history_loader.Channel = channel; history_loader.Stop = stop; history_loader.PatronBarcode = strBarcode; history_loader.TimeRange = strTimeRange; history_loader.Actions = "return,lost"; history_loader.Order = "descending"; CacheableBiblioLoader summary_loader = new CacheableBiblioLoader(); summary_loader.Channel = channel; summary_loader.Stop = stop; summary_loader.Format = "summary"; summary_loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; // summary_loader.RecPaths = biblio_recpaths; // 输出借阅历史表格 // 可能会抛出异常,例如权限不够 OutputBorrowHistory(sheet, dom, history_loader, // this.MainForm.GetBiblioSummary, summary_loader, ref nRowIndex, ref column_max_chars); } catch (Exception ex) { strError = "输出借阅历史时出现异常: " + ex.Message; return -1; } finally { Program.MainForm.ReturnChannel(channel); } } nRowIndex++; // 读者之间的空行 nReaderIndex++; if (stop != null) stop.SetProgressValue(nReaderIndex); } { if (stop != null) stop.SetMessage("正在调整列宽度 ..."); Application.DoEvents(); // 字符数太多的列不要做 width auto adjust foreach (IXLColumn column in sheet.Columns()) { int MAX_CHARS = 50; // 60 int nIndex = column.FirstCell().Address.ColumnNumber - 1; if (nIndex >= column_max_chars.Count) break; int nChars = column_max_chars[nIndex]; if (nIndex == 1) { column.Width = 10; continue; } if (nIndex == 3) MAX_CHARS = 50; else MAX_CHARS = 24; if (nChars < MAX_CHARS) column.AdjustToContents(); else column.Width = Math.Min(MAX_CHARS, nChars); } } } finally { if (doc != null) { doc.SaveAs(dlg.FileName); doc.Dispose(); } if (bLaunchExcel) { try { System.Diagnostics.Process.Start(dlg.FileName); } catch { } } } return 1; }