// 装入一个日志文件中的若干记录 // parameters: // strStyle 如果包含 accessLog,表示这是需要获取只读日志 // strCacheDir 存储本地缓存文件的目录 // lServerFileSize 服务器端日志文件的尺寸。如果为-1,表示函数内会自动获取 // lSize 进度条所采用的最大尺寸。如果必要,可能会被本函数推动 // return: // -2 此类型的日志尚未启用 // -1 error // 0 正常结束 // 1 用户中断 static int ProcessFile( IWin32Window owner, Stop stop, ProgressEstimate estimate, LibraryChannel channel, string strLogFileName, int nLevel, long lServerFileSize, string strRange, string strStyle, string strCacheDir, object param, Delegate_doRecord procDoRecord, ref long lProgressValue, ref long lSize, out string strError) { strError = ""; int nRet = 0; long lRet = 0; stop.SetMessage("正在装入日志文件 " + strLogFileName + " 中的记录。" + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed)); bool bAccessLog = StringUtil.IsInList("accessLog", strStyle); string strXml = ""; long lAttachmentTotalLength = 0; byte[] attachment_data = null; long lFileSize = 0; if (lServerFileSize == -1) { lServerFileSize = 0; string strTempStyle = "level-" + nLevel.ToString(); if (bAccessLog) strTempStyle += ",accessLog"; // 获得服务器端日志文件尺寸 lRet = channel.GetOperLog( stop, strLogFileName, -1, // lIndex, -1, // lHint, strTempStyle, "", // strFilter out strXml, out lServerFileSize, 0, // lAttachmentFragmentStart, 0, // nAttachmentFramengLength, out attachment_data, out lAttachmentTotalLength, out strError); // 2015/11/25 if (lRet == -1) return -1; // 2010/12/13 if (lRet == 0) return 0; if (lServerFileSize == -1) { strError = "日志尚未启用"; return -2; } } Stream stream = null; bool bCacheFileExist = false; bool bRemoveCacheFile = false; // 是否要自动删除未全部完成的本地缓存文件 bool bAutoCache = StringUtil.IsInList("autocache", strStyle); if (bAutoCache == true) { nRet = PrepareCacheFile( strCacheDir, bAccessLog ? strLogFileName + ".a" : strLogFileName, lServerFileSize, out bCacheFileExist, out stream, out strError); if (nRet == -1) return -1; if (bCacheFileExist == false && stream != null) bRemoveCacheFile = true; } try { if (bCacheFileExist == true) lFileSize = stream.Length; else lFileSize = lServerFileSize; // stop.SetProgressRange(0, lTotalSize); if (String.IsNullOrEmpty(strRange) == true) strRange = "0-9999999999"; RangeList rl = new RangeList(strRange); for (int i = 0; i < rl.Count; i++) { RangeItem ri = (RangeItem)rl[i]; OperLogInfo[] records = null; long lStartRecords = 0; long lHint = -1; long lHintNext = -1; for (long lIndex = ri.lStart; lIndex < ri.lStart + ri.lLength; lIndex++) { Application.DoEvents(); if (stop != null) { if (stop.State != 0) { strError = "用户中断1"; goto ERROR1; } } if (lIndex == ri.lStart) lHint = -1; else lHint = lHintNext; if (bCacheFileExist == true) { if (lHint == -1) { // return: // -1 error // 0 成功 // 1 到达文件末尾或者超出 nRet = LocationRecord(stream, lIndex, out strError); if (nRet == -1) return -1; } else { // 根据暗示找到 if (lHint == stream.Length) break; if (lHint > stream.Length) { strError = "lHint参数值不正确"; return -1; } if (stream.Position != lHint) stream.Seek(lHint, SeekOrigin.Begin); } nRet = ReadCachedEnventLog( stream, out strXml, out lAttachmentTotalLength, out strError); if (nRet == -1) return -1; lHintNext = stream.Position; } else { if (records == null || lIndex - ri.lStart >= lStartRecords + records.Length) { int nCount = -1; if (ri.lLength >= Int32.MaxValue) nCount = -1; else nCount = (int)ri.lLength; string strTempStyle = "level-" + nLevel.ToString(); if (bAccessLog) strTempStyle += ",accessLog"; // 获得日志 // return: // -1 error // 0 file not found // 1 succeed // 2 超过范围,本次调用无效 lRet = channel.GetOperLogs( stop, strLogFileName, lIndex, lHint, nCount, strTempStyle, "", // strFilter out records, out strError); if (lRet == -1) { DialogResult result = MessageBox.Show(owner, strError + "\r\n\r\n是否继续处理?", "OperLogForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.No) goto ERROR1; else { // TODO: 是否要在listview中装入一条表示出错的行? lHintNext = -1; continue; } } if (lRet == 0) return 0; if (lRet == 2) break; // records数组表示的起点位置 lStartRecords = lIndex - ri.lStart; } OperLogInfo info = records[lIndex - lStartRecords]; strXml = info.Xml; lHintNext = info.HintNext; lAttachmentTotalLength = info.AttachmentLength; // 写入本地缓存的日志文件 if (stream != null) { try { WriteCachedEnventLog( stream, strXml, lAttachmentTotalLength); } catch (Exception ex) { strError = "写入本地缓存文件的时候出错: " + ex.Message; return -1; } } } #if NO // 2011/12/30 // 日志记录可能动态地增加了,超过了原先为ProgressBar设置的范围 if (lFizeTotalSize < (int)lHintNext) { lFizeTotalSize = lHintNext; stop.SetProgressRange(0, lFizeTotalSize); } #endif if (lHintNext >= 0) { // 校正 if (lProgressValue + lHintNext > lSize) { lSize = lProgressValue + lHintNext; stop.SetProgressRange(0, lSize); estimate.SetRange(0, lSize); } stop.SetProgressValue(lProgressValue + lHintNext); } if (lIndex % 100 == 0) { stop.SetMessage("正在装入日志文件 " + strLogFileName + " 中的记录 " + lIndex.ToString() + " 。" + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue + lHintNext)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed)); } // if (procDoRecord != null) { nRet = procDoRecord(strLogFileName, strXml, bCacheFileExist, lHint, lIndex, lAttachmentTotalLength, param, out strError); if (nRet == -1) { DialogResult result = MessageBox.Show(owner, strLogFileName + " : " + lIndex.ToString() + "\r\n" + strError + "\r\n\r\n是否继续处理?", "OperLogForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.No) return -1; } if (nRet == 1) return 1; } } } // 创建本地缓存的日志文件的metadata文件 if (bCacheFileExist == false && stream != null) { nRet = CreateCacheMetadataFile( strCacheDir, bAccessLog ? strLogFileName + ".a" : strLogFileName, lServerFileSize, out strError); if (nRet == -1) goto ERROR1; } bRemoveCacheFile = false; // 不删除 } finally { if (stream != null) stream.Close(); if (bRemoveCacheFile == true) { string strError1 = ""; nRet = DeleteCacheFile( strCacheDir, bAccessLog ? strLogFileName + ".a" : strLogFileName, out strError1); if (nRet == -1) MessageBox.Show(owner, strError1); } } lProgressValue += lFileSize; return 0; ERROR1: return -1; }
int ProcessSelectedRecords(Delegate_processLog func, out string strError) { strError = ""; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选定要处理的行"; return -1; } Stop stop = new DigitalPlatform.Stop(); stop.Register(MainForm.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStopPrint); stop.Initial("正在处理日志记录 ..."); stop.BeginLoop(); try { stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); int i = 0; foreach (ListViewItem item in this.listView_records.SelectedItems) { Application.DoEvents(); if (stop != null && stop.State != 0) { strError = "用户中断"; return -1; } OperLogItemInfo info = (OperLogItemInfo)item.Tag; string strLogFileName = ListViewUtil.GetItemText(item, COLUMN_FILENAME); string strIndex = ListViewUtil.GetItemText(item, COLUMN_INDEX); string strXml = ""; // 从服务器获得 // return: // -1 出错 // 0 正常 // 1 用户中断 int nRet = GetXml(item, out strXml, out strError); if (nRet == 1) return -1; if (nRet == -1) return -1; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "装载日志记录 '" + strLogFileName + ":" + strIndex + "' XML 到 DOM 时发生错误: " + ex.Message; return -1; } if (func != null) { if (func(strLogFileName, Convert.ToInt32(strIndex), dom, null) == false) break; } stop.SetProgressValue(i + 1); i++; } return 0; } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStopPrint); stop.Initial("处理完成"); stop.HideProgress(); if (stop != null) // 脱离关联 { stop.Unregister(); // 和容器关联 stop = null; } } }
// 打印解释内容 void menu_printHtml_Click(object sender, EventArgs e) { string strError = ""; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选定要打印的行"; goto ERROR1; } List<string> filenames = new List<string>(); string strFileNamePrefix = this.MainForm.DataDir + "\\~operlog_print_"; string strFilename = strFileNamePrefix + (1).ToString() + ".html"; filenames.Add(strFilename); File.Delete(strFilename); StreamUtil.WriteText(strFilename, "<html>" + GetHeadString(false) + "<body>"); Stop stop = new DigitalPlatform.Stop(); stop.Register(MainForm.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStopPrint); stop.Initial("正在创建打印页面 ..."); stop.BeginLoop(); m_webExternalHost = new WebExternalHost(); m_webExternalHost.Initial(this.MainForm, null); m_webExternalHost.IsInLoop = true; this.GetSummary += new GetSummaryEventHandler(OperLogForm_GetSummary); try { stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); int i = 0; foreach (ListViewItem item in this.listView_records.SelectedItems) { Application.DoEvents(); if (stop != null && stop.State != 0) { strError = "用户中断"; goto ERROR1; } OperLogItemInfo info = (OperLogItemInfo)item.Tag; string strLogFileName = ListViewUtil.GetItemText(item, COLUMN_FILENAME); string strIndex = ListViewUtil.GetItemText(item, COLUMN_INDEX); string strXml = ""; // 从服务器获得 // return: // -1 出错 // 0 正常 // 1 用户中断 int nRet = GetXml(item, out strXml, out strError); if (nRet == 1) return; if (nRet == -1) goto ERROR1; Global.SetXmlString(this.webBrowser_xml, strXml, this.MainForm.DataDir, "operlogexml"); string strHtml = ""; // 创建解释日志记录内容的 HTML 字符串 // return: // -1 出错 // 0 成功 // 1 未知的操作类型 nRet = GetHtmlString(strXml, false, out strHtml, out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) strHtml = strError; StreamUtil.WriteText(strFilename, "<p class='record_title'>" + strLogFileName + " : " + strIndex + "</p>" + strHtml); stop.SetProgressValue(i + 1); i++; } } finally { this.GetSummary -= new GetSummaryEventHandler(OperLogForm_GetSummary); if (m_webExternalHost != null) { m_webExternalHost.IsInLoop = false; m_webExternalHost.Destroy(); m_webExternalHost = null; } stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStopPrint); stop.Initial("打印页面创建完成"); stop.HideProgress(); if (stop != null) // 脱离关联 { stop.Unregister(); // 和容器关联 stop = null; } } StreamUtil.WriteText(strFilename, "</body></html>"); // TODO: 浏览器控件连接javascript host HtmlPrintForm printform = new HtmlPrintForm(); printform.Text = "打印解释内容"; printform.MainForm = this.MainForm; printform.Filenames = filenames; this.MainForm.AppInfo.LinkFormState(printform, "operlogform_printform_state"); printform.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(printform); return; ERROR1: MessageBox.Show(this, strError); }
// parameters: // strFileType barcode/recpath // return: // -1 出错 // 0 放弃 // >=1 处理的条数 int ProcessFile( string strFileType, out string strError) { strError = ""; string strFilename = ""; if (strFileType == "barcode") { if (string.IsNullOrEmpty(this.textBox_barcodeFile.Text) == true) { OpenFileDialog dlg = new OpenFileDialog(); dlg.FileName = this.textBox_barcodeFile.Text; dlg.Title = "请指定要打开的条码号文件名"; dlg.Filter = "条码号文件 (*.txt)|*.txt|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) { return(0); } this.textBox_barcodeFile.Text = dlg.FileName; } strFilename = this.textBox_barcodeFile.Text; } else if (strFileType == "recpath") { if (string.IsNullOrEmpty(this.textBox_recPathFile.Text) == true) { OpenFileDialog dlg = new OpenFileDialog(); dlg.FileName = this.textBox_recPathFile.Text; dlg.Title = "请指定要打开的记录路径文件名"; dlg.Filter = "记录路径文件 (*.txt)|*.txt|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) { return(0); } this.textBox_recPathFile.Text = dlg.FileName; } strFilename = this.textBox_recPathFile.Text; } else { strError = "未知的 strFileType '" + strFilename + "'"; return(-1); } // 探测文本文件的行数 // parameters: // bIncludeBlankLine 是包括空行 // return: // -1 出错 // >=0 行数 long lLineCount = GetTextLineCount(strFilename, false); if (lLineCount != -1) { stop.SetProgressRange(0, lLineCount); } int nCurrentLine = 0; StreamReader sr = null; try { this.textBox_outputBarcodes.Text = ""; // 打开文件 sr = new StreamReader(strFilename); EnableControls(false); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在初始化浏览器组件 ..."); stop.BeginLoop(); this.Update(); this.MainForm.Update(); try { int nRet = 0; // 逐行读入文件内容 for (; ;) { Application.DoEvents(); if (stop != null) { if (stop.State != 0) { strError = "用户中断1"; return(-1); } } string strLine = ""; strLine = sr.ReadLine(); if (strLine == null) { break; } strLine = strLine.Trim(); if (String.IsNullOrEmpty(strLine) == true) { continue; } if (strFileType == "barcode") { stop.SetMessage("正在处理册条码号 " + strLine + " 对应的记录..."); } else { stop.SetMessage("正在处理记录路径 " + strLine + " 对应的记录..."); } stop.SetProgressValue(nCurrentLine); nCurrentLine++; // 先保存前一条 if (this.entityEditControl1.Changed == true) { nRet = DoSave(false, out strError); if (nRet == -1) { MessageBox.Show(this, strError); } } // DOLOAD: nRet = LoadRecord(false, strFileType == "barcode" ? strLine : "@path:" + strLine, out strError); if (nRet != 1) { this.textBox_outputBarcodes.Text += "# " + strLine + " " + strError + "\r\n"; continue; } // 自动修改 // return: // 0 没有实质性改变 // 1 有实质性改变 AutoChangeData(); if (this.entityEditControl1.Changed == true) { nRet = DoSave(false, out strError); if (nRet == -1) { this.textBox_outputBarcodes.Text += "# " + strLine + " " + strError + "\r\n"; continue; } if (nRet != -1) { this.textBox_outputBarcodes.Text += strLine + "\r\n"; } } else { this.textBox_outputBarcodes.Text += "# " + strLine + "\r\n"; } } } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); EnableControls(true); } return(nCurrentLine); } catch (Exception ex) { strError = "QuickChangeEntityForm ProcessFile() exception: " + ExceptionUtil.GetAutoText(ex); return(-1); } finally { if (sr != null) { sr.Close(); } } }
// return: // -1 出错 // 0 放弃处理 // 1 正常结束 int DoTextLines() { string strError = ""; int nRet = 0; if (String.IsNullOrEmpty(this.textBox_paths.Text) == true) { strError = "尚未指定任何路径"; goto ERROR1; } // TODO: MessageBox提示将要进行的修改动作。并警告不能复原 // TODO: 检查修改动作,警告那种什么都不修改的情况 string strInfo = GetSummary(); if (String.IsNullOrEmpty(strInfo) == true) { DialogResult result = MessageBox.Show(this, "当前没有任何修改动作。确实要启动处理?", "dp2Circulation", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Cancel) { return(0); } } else { DialogResult result = MessageBox.Show(this, "即将进行下述修改动作:\r\n---" + strInfo + "\r\n\r\n开始处理?", "dp2Circulation", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Cancel) { return(0); } } int nCount = 0; // 总共处理多少条 int nChangedCount = 0; // 发生修改的有多少条 DateTime now = DateTime.Now; stop.SetProgressRange(0, this.textBox_paths.Lines.Length); for (int i = 0; i < this.textBox_paths.Lines.Length; i++) { Application.DoEvents(); if (stop != null) { if (stop.State != 0) { strError = "用户中断1"; goto ERROR1; } } string strLine = this.textBox_paths.Lines[i].Trim(); nRet = strLine.IndexOfAny(new char[] { ' ', '\t' }); if (nRet != -1) { strLine = strLine.Substring(0, nRet).Trim(); } if (String.IsNullOrEmpty(strLine) == true) { continue; } nRet = ChangeOneRecord(strLine, now, out strError); if (nRet == -1) { goto ERROR1; } nCount++; if (nRet == 1) { nChangedCount++; } stop.SetProgressValue(i + 1); } MessageBox.Show(this, "处理完毕。共处理记录 " + nCount.ToString() + " 条,实际发生修改 " + nChangedCount.ToString() + " 条"); return(1); ERROR1: MessageBox.Show(this, strError); return(-1); }
// 为选定的行装入Full元素集的记录 public void ReloadFullElementSet() { string strError = ""; int nRet = 0; ZConnection connection = this.GetCurrentZConnection(); if (connection == null) { strError = "当前ZConnection为空"; goto ERROR1; } if (connection.VirtualItems.SelectedIndices.Count == 0) { strError = "尚未选定要装入完整格式的浏览行"; goto ERROR1; } DigitalPlatform.Stop stop = null; stop = new DigitalPlatform.Stop(); stop.Register(this.MainForm.stopManager, true); // 和容器关联 stop.BeginLoop(); this.EnableControls(false); try { List<int> selected = new List<int>(); selected.AddRange(connection.VirtualItems.SelectedIndices); stop.SetProgressRange(0, selected.Count); for (int i = 0; i < selected.Count; i++) { Application.DoEvents(); // 出让界面控制权 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; goto ERROR1; } } int index = selected[i]; stop.SetMessage("正在重新装载记录 "+(index+1).ToString()+" 的详细格式..."); byte[] baTimestamp = null; string strSavePath = ""; string strOutStyle = ""; LoginInfo logininfo = null; long lVersion = 0; string strXmlFragment = ""; DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; string strMARC = ""; nRet = this.GetOneRecord( "marc", index, // 即将废止 "index:" + index.ToString(), "force_full", // false, out strSavePath, out strMARC, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) goto ERROR1; stop.SetProgressValue(i); } return; } finally { stop.EndLoop(); stop.SetMessage(""); stop.Unregister(); // 和容器关联 stop = null; this.EnableControls(true); } // return 0; ERROR1: MessageBox.Show(this, strError); }
// parameters: // output_columns 输出列定义。如果为空,表示全部输出。这是一个数字列表,例如 "1,2,3,5" // return: // -1 出错 // 0 放弃或中断 // 1 成功 public static int ExportToExcel( Stop stop, ListView list, List<string> output_columns, List<ListViewItem> items, IXLWorksheet sheet, out string strError) { strError = ""; #if NO if (items == null || items.Count == 0) { strError = "items == null || items.Count == 0"; return -1; } #endif // ListView list = items[0].ListView; if (stop != null) stop.SetProgressRange(0, items.Count); List<int> indices = new List<int>(); if (output_columns == null && output_columns.Count == 0) { int i = 0; foreach (ColumnHeader header in list.Columns) { indices.Add(i++); } } else { foreach (string s in output_columns) { int v = 0; if (Int32.TryParse(s, out v) == false) { strError = "output_columns 数组中有非数字的字符串,格式错误"; return -1; } indices.Add(v - 1); // 从 0 开始计数 } } // 每个列的最大字符数 List<int> column_max_chars = new List<int>(); List<XLAlignmentHorizontalValues> alignments = new List<XLAlignmentHorizontalValues>(); //foreach (ColumnHeader header in list.Columns) foreach (int index in indices) { ColumnHeader header = list.Columns[index]; if (header.TextAlign == HorizontalAlignment.Center) alignments.Add(XLAlignmentHorizontalValues.Center); else if (header.TextAlign == HorizontalAlignment.Right) alignments.Add(XLAlignmentHorizontalValues.Right); else alignments.Add(XLAlignmentHorizontalValues.Left); column_max_chars.Add(0); } string strFontName = list.Font.FontFamily.Name; int nRowIndex = 1; int nColIndex = 1; // foreach (ColumnHeader header in list.Columns) foreach (int index in indices) { ColumnHeader header = list.Columns[index]; IXLCell cell = sheet.Cell(nRowIndex, nColIndex).SetValue(header.Text); cell.Style.Alignment.WrapText = true; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; cell.Style.Font.Bold = true; cell.Style.Font.FontName = strFontName; cell.Style.Alignment.Horizontal = alignments[nColIndex - 1]; nColIndex++; } nRowIndex++; //if (stop != null) // stop.SetMessage(""); foreach (ListViewItem item in items) { Application.DoEvents(); if (stop != null && stop.State != 0) { strError = "用户中断"; return 0; } // List<CellData> cells = new List<CellData>(); nColIndex = 1; // foreach (ListViewItem.ListViewSubItem subitem in item.SubItems) foreach (int index in indices) { string strText = ""; ListViewItem.ListViewSubItem subitem = null; if (index < item.SubItems.Count) { subitem = item.SubItems[index]; strText = subitem.Text; } else { } // 统计最大字符数 int nChars = column_max_chars[nColIndex - 1]; if (string.IsNullOrEmpty(strText) == false && strText.Length > nChars) { column_max_chars[nColIndex - 1] = strText.Length; } IXLCell cell = sheet.Cell(nRowIndex, nColIndex).SetValue(strText); cell.Style.Alignment.WrapText = true; cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; cell.Style.Font.FontName = strFontName; cell.Style.Alignment.Horizontal = alignments[nColIndex - 1]; nColIndex++; } if (stop != null) stop.SetProgressValue(nRowIndex - 1); nRowIndex++; } if (stop != null) stop.SetMessage("正在调整列宽度 ..."); Application.DoEvents(); double char_width = ClosedXmlUtil.GetAverageCharPixelWidth(list); // 字符数太多的列不要做 width auto adjust const int MAX_CHARS = 30; // 60 { int i = 0; foreach (IXLColumn column in sheet.Columns()) { int nChars = column_max_chars[i]; if (nChars < MAX_CHARS) column.AdjustToContents(); else column.Width = (double)list.Columns[i].Width / char_width; // Math.Min(MAX_CHARS, nChars); i++; } } 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; }