From 26a25c1410be077b32145a9ac0191a32763de881 Mon Sep 17 00:00:00 2001
From: gaofei1985 <181547018@qq.com>
Date: Wed, 24 Jun 2026 15:54:24 +0800
Subject: [PATCH] 1
---
.gitignore | 1 +
HJGL_DS/BLL/Common/FastReportService.cs | 210 ++++++++++++++----
HJGL_DS/FineUIPro.Web/Global.asax.cs | 1 +
.../WeldMat/UsingSentMat/UsingMatCheck.aspx | 55 ++++-
.../UsingSentMat/UsingMatCheck.aspx.cs | 7 +-
5 files changed, 220 insertions(+), 54 deletions(-)
diff --git a/.gitignore b/.gitignore
index 63094fa..5aa11bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,4 @@ bin-release/
/CreateModel2017.bat
*.xls
/HJGL_DS/FineUIPro.Web/File/PDF/Pipe
+/HJGL_DS/FineUIPro.Web/File/Fastreport/Temp
diff --git a/HJGL_DS/BLL/Common/FastReportService.cs b/HJGL_DS/BLL/Common/FastReportService.cs
index 8256bba..8bd5b05 100644
--- a/HJGL_DS/BLL/Common/FastReportService.cs
+++ b/HJGL_DS/BLL/Common/FastReportService.cs
@@ -8,78 +8,195 @@ using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
+using System.Timers;
+using System;
+using FastReport.Export.Pdf;
+using System.IO;
namespace BLL.Common
{
public static class FastReportService
{
+ private static Timer tempReportCleanupTimer;
// 缓存过期时间:30分钟
private static readonly int CacheExpirationMinutes = 5;
///
- /// 重置数据 - 清理缓存和Session
+ /// 重置数据
///
public static void ResetData()
{
- if (HttpContext.Current?.Session == null)
+ HttpContext.Current.Session["ReportDataTables"] = null;
+ HttpContext.Current.Session["ReportParameterValues"] = null;
+ }
+ public static void AddFastreportTable(DataTable dataTable)
+ {
+ List dataTables = (List)HttpContext.Current.Session["ReportDataTables"];
+ if (dataTables == null)
{
- return;
+ dataTables = new List();
+ }
+ dataTables.Add(dataTable);
+
+ HttpContext.Current.Session["ReportDataTables"] = dataTables;
+ }
+ public static void AddFastreportParameter(Dictionary Dicparames)
+ {
+ HttpContext.Current.Session["ReportParameterValues"] = Dicparames;
+
+ }
+
+ ///
+ /// 启动临时报表清理定时器,定期删除超过 1 小时的 PDF。
+ ///
+ public static void StartTempReportCleanupMonitor()
+ {
+ if (tempReportCleanupTimer != null)
+ {
+ tempReportCleanupTimer.Stop();
+ tempReportCleanupTimer.Dispose();
+ tempReportCleanupTimer = null;
}
- // 清理Session中的缓存键引用
- var cacheKeys = HttpContext.Current.Session["ReportDataCacheKeys"] as List;
- if (cacheKeys != null)
+ CleanExpiredTempReports();
+ tempReportCleanupTimer = new Timer
{
- foreach (var key in cacheKeys)
+ AutoReset = true,
+ Interval = 1000 * 60 * 30
+ };
+ tempReportCleanupTimer.Elapsed += TempReportCleanupTimer_Elapsed;
+ tempReportCleanupTimer.Start();
+ }
+
+ private static void TempReportCleanupTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ CleanExpiredTempReports();
+ }
+
+ ///
+ /// 删除 File/Fastreport/Temp 下创建时间超过 1 小时的 PDF 临时文件。
+ ///
+ public static void CleanExpiredTempReports()
+ {
+ try
+ {
+ string tempDirectory = Path.Combine(Funs.RootPath, @"File\Fastreport\Temp\");
+ if (!Directory.Exists(tempDirectory))
{
- try
+ return;
+ }
+
+ DateTime expiredTime = DateTime.Now.AddHours(-1);
+ foreach (string file in Directory.GetFiles(tempDirectory, "*.pdf", SearchOption.TopDirectoryOnly))
+ {
+ FileInfo fileInfo = new FileInfo(file);
+ if (fileInfo.CreationTime < expiredTime)
{
- CacheHelper.Remove(key);
- }
- catch
- {
- // 忽略缓存删除异常
+ fileInfo.Attributes = FileAttributes.Normal;
+ fileInfo.Delete();
}
}
}
- HttpContext.Current.Session["ReportDataCacheKeys"] = null;
- HttpContext.Current.Session["ReportParameterCacheKey"] = null;
- }
-
- ///
- /// 添加报表数据表到缓存
- ///
- public static void AddFastreportTable(DataTable dataTable)
- {
-
- // 生成唯一缓存键
- string cacheKey = $"ReportData_{Guid.NewGuid()}_{DateTime.Now.Ticks}";
-
- // 将数据表存储到缓存中,设置5分钟过期
- CacheHelper.Add(cacheKey, dataTable, DateTimeOffset.Now.AddMinutes(CacheExpirationMinutes));
-
- List cacheKeys = HttpContext.Current.Session["ReportDataCacheKeys"] as List;
- if (cacheKeys==null)
+ catch (Exception ex)
{
- cacheKeys = new List();
+ ErrLogInfo.WriteLog(ex, "FastReport临时报表清理", "FastReportService.CleanExpiredTempReports");
}
- cacheKeys.Add(cacheKey);
- HttpContext.Current.Session["ReportDataCacheKeys"] = cacheKeys;
}
///
- /// 添加报表参数到缓存
+ /// 导出报表 PDF 到临时目录,并返回可访问的相对 URL。
///
- public static void AddFastreportParameter(Dictionary Dicparames)
- {
- // 生成唯一缓存键
- string cacheKey = $"ReportParam_{Guid.NewGuid()}_{DateTime.Now.Ticks}";
+ /// 报表模板路径,支持绝对路径或相对 Funs.RootPath 的路径。
+ public static string ExportReport(string reportPath)
+ {
+ List dataTables = (List)HttpContext.Current.Session["ReportDataTables"];
+ Dictionary parameterValues = (Dictionary)HttpContext.Current.Session["ReportParameterValues"];
+ return ExportReport(reportPath, dataTables, parameterValues);
+ }
- // 将参数存储到缓存中,设置5分钟过期
- CacheHelper.Add(cacheKey, Dicparames, DateTimeOffset.Now.AddMinutes(CacheExpirationMinutes));
+ ///
+ /// 导出报表 PDF 到临时目录,并返回可访问的相对 URL。
+ ///
+ /// 报表模板路径,支持绝对路径或相对 Funs.RootPath 的路径。
+ /// 报表数据源集合。
+ /// 报表参数集合。
+ public static string ExportReport(string reportPath, List dataTables, Dictionary parameterValues)
+ {
+ string fullReportPath = GetReportFullPath(reportPath);
+ if (string.IsNullOrEmpty(fullReportPath) || !File.Exists(fullReportPath))
+ {
+ throw new FileNotFoundException("打印模板不存在!", reportPath);
+ }
- // Session只存储缓存键的引用(轻量级)
- HttpContext.Current.Session["ReportParameterCacheKey"] = cacheKey;
+ string relativeDirectory = @"File\Fastreport\Temp\";
+ string tempDirectory = Path.Combine(Funs.RootPath, relativeDirectory);
+ if (!Directory.Exists(tempDirectory))
+ {
+ Directory.CreateDirectory(tempDirectory);
+ }
+
+ string fileName = "report_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + Guid.NewGuid().ToString("N") + ".pdf";
+ string filePath = Path.Combine(tempDirectory, fileName);
+ using (Report report = BuildPreparedReport(fullReportPath, dataTables, parameterValues))
+ using (PDFExport pdfExport = new PDFExport())
+ {
+ // Web 打印先导出 PDF,前端用 iframe 装载后调用浏览器打印。
+ pdfExport.PrintScaling = false;
+ pdfExport.ShowPrintDialog = true;
+ report.Export(pdfExport, filePath);
+ }
+
+ return "~/" + relativeDirectory.Replace("\\", "/") + fileName;
+ }
+
+ private static Report BuildPreparedReport(string reportPath, List dataTables, Dictionary parameterValues)
+ {
+ FastReport.Utils.Config.WebMode = true;
+ Report report = new Report();
+ report.Load(reportPath);
+ if (report.Dictionary.Connections.Count > 0)
+ {
+ var reportConnection = report.Dictionary.Connections[0];
+ if (reportConnection.ConnectionString != Funs.ConnString)
+ {
+ // 打印时只替换本次报表连接,避免把运行环境连接串写回模板文件。
+ reportConnection.ConnectionString = Funs.ConnString;
+ }
+ }
+
+ if (dataTables != null && dataTables.Count > 0)
+ {
+ for (int i = 0; i < dataTables.Count; i++)
+ {
+ report.RegisterData(dataTables[i], dataTables[i].TableName);
+ }
+ }
+
+ if (parameterValues != null && parameterValues.Count > 0)
+ {
+ foreach (KeyValuePair kvp in parameterValues)
+ {
+ report.SetParameterValue(kvp.Key, kvp.Value);
+ }
+ }
+
+ report.Prepare();
+ return report;
+ }
+
+ private static string GetReportFullPath(string reportPath)
+ {
+ if (string.IsNullOrEmpty(reportPath))
+ {
+ return reportPath;
+ }
+
+ if (Path.IsPathRooted(reportPath))
+ {
+ return reportPath;
+ }
+
+ return Path.Combine(Funs.RootPath, reportPath.TrimStart('\\', '/'));
}
///
@@ -105,26 +222,21 @@ namespace BLL.Common
{
report.RegisterData(dataTables[j], dataTables[j].TableName);//绑定数据源
}
-
}
if (ParameterValues.Count > 0)
{
foreach (KeyValuePair kvp in ParameterValues)
{
- report.SetParameterValue(kvp.Key, kvp.Value);//绑定参数
-
+ report.SetParameterValue(kvp.Key, kvp.Value);//绑定参数
}
-
}
if (i == 0)
{
report.Prepare();
-
}
else
{
report.Prepare(true);
-
}
}
if (printType == "1")
diff --git a/HJGL_DS/FineUIPro.Web/Global.asax.cs b/HJGL_DS/FineUIPro.Web/Global.asax.cs
index bc83077..edd3b97 100644
--- a/HJGL_DS/FineUIPro.Web/Global.asax.cs
+++ b/HJGL_DS/FineUIPro.Web/Global.asax.cs
@@ -37,6 +37,7 @@
Funs.APPUrl = ConfigurationManager.AppSettings["APPUrl"];
Funs.SystemCode = ConfigurationManager.AppSettings["SystemCode"];
Funs.HJGLUrl = ConfigurationManager.AppSettings["HJGLUrl"];
+ BLL.Common.FastReportService.StartTempReportCleanupMonitor();
}
catch (Exception ex)
{
diff --git a/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx b/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx
index 002c995..45873cd 100644
--- a/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx
+++ b/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx
@@ -80,15 +80,64 @@
var result = window.showModalDialog("LC700.aspx?keyId=" + keyId + "&flag=" + flag + "&grid=" + grid, "", "status=no;dialogWidth=600px;dialogHeight=280px;menu=no;resizeable=no;scroll=yes;center=yes;edge=raise;location=no");
}
- function ReportPrint(reportId, replaceParameter, varValue) {
- var result = window.showModalDialog("../../Common/ReportPrint/ExReportPrint.aspx?ispop=1&projectId=0&reportId=" + reportId + "&replaceParameter=" + replaceParameter + "&varValue=" + varValue, "", "status=no;dialogWidth=610px;dialogHeight=460px;menu=no;resizeable=no;scroll=no;center=yes;edge=raise;location=no");
- }
+ //function ReportPrint(reportId, replaceParameter, varValue) {
+ // var result = window.showModalDialog("../../Common/ReportPrint/ExReportPrint.aspx?ispop=1&projectId=0&reportId=" + reportId + "&replaceParameter=" + replaceParameter + "&varValue=" + varValue, "", "status=no;dialogWidth=610px;dialogHeight=460px;menu=no;resizeable=no;scroll=no;center=yes;edge=raise;location=no");
+ //}
function backData(data) {
//debugger
//alert(data);
alert("焊工已确认领料!");
}
+
+ function printByHiddenFrame(url) {
+ var frameId = 'fastreport-print-frame-' + new Date().getTime();
+ var frame = document.createElement('iframe');
+ frame.id = frameId;
+ frame.name = frameId;
+ frame.style.position = 'fixed';
+ frame.style.left = '-10000px';
+ frame.style.top = '-10000px';
+ frame.style.width = '1px';
+ frame.style.height = '1px';
+ frame.style.border = '0';
+ frame.style.opacity = '0';
+ frame.onload = function () {
+ setTimeout(function () {
+ try {
+ frame.contentWindow.onafterprint = cleanupPrintFrame;
+ frame.contentWindow.focus();
+ frame.contentWindow.print();
+ } catch (e) {
+ window.print();
+ }
+ }, 500);
+ };
+ frame.src = url;
+ document.body.appendChild(frame);
+ var cleaned = false;
+ function cleanupPrintFrame() {
+ if (cleaned) {
+ return;
+ }
+ cleaned = true;
+ if (frame && frame.parentNode) {
+ frame.parentNode.removeChild(frame);
+ }
+ window.removeEventListener('afterprint', cleanupPrintFrame);
+ }
+ window.addEventListener('afterprint', cleanupPrintFrame);
+ setTimeout(cleanupPrintFrame, 300000);
+ }
+ window.addEventListener('message', function (event) {
+ if (!event.data || event.data.type !== 'fastreport-print-finished') {
+ return;
+ }
+ var frame = document.getElementById(event.data.frameId);
+ if (frame && frame.parentNode) {
+ frame.parentNode.removeChild(frame);
+ }
+ });
diff --git a/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx.cs b/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx.cs
index aa66c47..fb6889b 100644
--- a/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx.cs
+++ b/HJGL_DS/FineUIPro.Web/WeldMat/UsingSentMat/UsingMatCheck.aspx.cs
@@ -316,8 +316,11 @@ namespace FineUIPro.Web.WeldMat.UsingSentMat
if (File.Exists(rootPath + initTemplatePath))
{
- PageContext.RegisterStartupScript(Window2.GetShowReference(String.Format("../../common/ReportPrint/Fastreport.aspx?ReportPath={0}", rootPath + initTemplatePath)));
-
+ //PageContext.RegisterStartupScript(Window2.GetShowReference(String.Format("../../common/ReportPrint/Fastreport.aspx?ReportPath={0}", rootPath + initTemplatePath)));
+ string printUrl = ResolveUrl(BLL.Common.FastReportService.ExportReport(rootPath + initTemplatePath));
+ PageContext.RegisterStartupScript(String.Format("printByHiddenFrame('{0}');", printUrl));
+ Window2.Hidden = true;
+ Window2.IFrameUrl = "";
}
}
}