diff --git a/end/reportWeb/Controllers/DesignController.cs b/end/reportWeb/Controllers/DesignController.cs index aedcefb..ac52275 100644 --- a/end/reportWeb/Controllers/DesignController.cs +++ b/end/reportWeb/Controllers/DesignController.cs @@ -75,7 +75,7 @@ private String getQueryValue(string name) return null; } public async Task Preview(String _content,String _ConnectionId,string reportName, - String _fresh_ds,String _fresh_params,bool _createFormParam,String _param_name) + String _fresh_ds,String _fresh_params,bool _createFormParam,String _param_name_) { List calcDsNames = null; List calcGridNames = null; @@ -178,7 +178,7 @@ public async Task Preview(String _content,String _ConnectionId,st if (_createFormParam == true) { exprFaced.addVariable("_createFormParam_", _createFormParam); - exprFaced.addVariable("_param_name_", _param_name); + exprFaced.addVariable("_param_name_", _param_name_); } exprFaced.addVariable("__page__", HttpContext.Request); Engine engine = new Engine(reportDefine); @@ -215,12 +215,12 @@ public async Task Preview(String _content,String _ConnectionId,st { reportWeb.Pages.ReportModel.output_expection(cur_exception, Report.getEnv().logger, Report.getEnv()); StringBuilder sb = new StringBuilder(); - while (cur_exception.InnerException != null) + do { sb.AppendLine(cur_exception.Message); cur_exception = cur_exception.InnerException; - } - jsonWriter.Write(",\"error\":"); + } while (cur_exception != null); + jsonWriter.Write(",\"errcode\":1,\"message\":"); jsonWriter.Write(JsonSerializer.Serialize(sb.ToString(), json_option)); } diff --git a/end/reportWeb/Controllers/PdfController.cs b/end/reportWeb/Controllers/PdfController.cs new file mode 100644 index 0000000..d1c9689 --- /dev/null +++ b/end/reportWeb/Controllers/PdfController.cs @@ -0,0 +1,379 @@ + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using iText.IO.Font; +using iText.Kernel.Font; +using iText.Kernel.Geom; +using iText.Kernel.Pdf; +using iText.Layout; +using iText.Layout.Element; +using Microsoft.AspNetCore.Mvc; +using System.Text.Json; +using CellReport.exporter; +using Microsoft.AspNetCore.Authorization; +using System.Collections; +using iText.Layout.Borders; +using iText.Kernel.Colors; +using System; +using iText.Layout.Properties; +using iText.Html2pdf; +using iText.Layout.Font; + +namespace reportWeb.Controllers +{ + public class PdfController : Controller + { + [HttpPost] + [AllowAnonymous] + public IActionResult Index(string report_obj, string paperSetting) + { + + PageSetup ps = null; + if (!string.IsNullOrEmpty(paperSetting) && "undefined" != paperSetting) + ps = JsonSerializer.Deserialize(paperSetting); + //var report_str = System.IO.File.ReadAllText(@"C:\Users\Administrator\Desktop\Untitled-1.json"); + return File(buildPdf(report_obj, ps), "application/pdf"); + } + + public static byte[] buildPdf(string report_str, PageSetup ps) + { + var json_root = JsonDocument.Parse(report_str).RootElement; + var json_data = json_root.GetProperty("data"); + //https://api.itextpdf.com/iText7/dotnet/latest/classi_text_1_1_layout_1_1_element_1_1_area_break.html + var grid_list = json_data.EnumerateObject().Select(x => x.Name).ToList(); + if (ps == null) + { + if (json_data.GetProperty(grid_list[0]).TryGetProperty("paperSetting", out var paperSetting_str) + && paperSetting_str.GetString() != null + ) + { + ps = JsonSerializer.Deserialize(paperSetting_str.GetString()); + } + else + ps = new PageSetup(); + } + if (ps.pageSize_name != "自定义") + { + PageSize _PageSize = typeof(PageSize).GetField(ps.pageSize_name.ToUpper()).GetValue(null) as PageSize; + if (ps.orientation == "landscape") + _PageSize = _PageSize.Rotate(); + ps.pageSize_Width = _PageSize.GetWidth(); + ps.pageSize_Height = _PageSize.GetHeight(); + } + + MemoryStream stream = new(); + PdfWriter writer = new(stream); + PdfDocument pdf = new(writer); + try + { + var default_font=CellReport.running.Template.getTemplate("template.xml").Get("FONT").content; + default_font=json_root.GetProperty("defaultsetting").GetProperty("FONT").GetString(); + if (converterProperties == null) + { + FontProvider fontProvider = new FontProvider(default_font); + fontProvider.AddSystemFonts(); + converterProperties = new ConverterProperties(); + converterProperties.SetFontProvider(fontProvider); + converterProperties.SetCharset("utf-8"); + converterProperties.SetBaseUri("http://127.0.0.1:5000/"); + } + Document pdf_doc = new(pdf, new PageSize(ps.pageSize_Width, ps.pageSize_Height) + , false); + pdf_doc.SetMargins(ps.margin_top, ps.margin_right, ps.margin_bottom, ps.margin_left); + PdfFont sysFont = PdfFontFactory.CreateRegisteredFont(default_font, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, true); + pdf_doc.SetFont(sysFont).SetFontSize(11);//设置字体大小 + + bool is_first = true; + foreach (var item in json_data.EnumerateObject()) + { + var rg = new ReportGridJSON(item.Value, ps); + rg.output(pdf_doc,ref is_first, addTable); + } + add_header_footer(ps, pdf, pdf_doc); + + //*/ + pdf_doc.Flush(); + } + finally + { + pdf.Close();//记得关闭PdfDocument和PdfWriter + writer.Close(); + } + return stream.ToArray(); + } + + private static ConverterProperties converterProperties = null; + + private static Paragraph convert_html_to_paragraph(string html) + { + var retpp = new Paragraph(); + var t_list=HtmlConverter.ConvertToElements(html, converterProperties); + foreach (var one_ele in t_list) + { + retpp.Add(one_ele as IBlockElement); + } + return retpp; + } + private static Paragraph replace_var_to_Paragraph(string str, int page_no, int page_all) + {//&[页码]&[总页数]&[日期]&[时间] + var t = str.Replace("&[页码]", page_no.ToString()) + .Replace("&[总页数]", page_all.ToString()) + .Replace("&[日期]", DateTime.Today.ToString("yyyy-MM-dd")) + .Replace("&[时间]", DateTime.Today.ToString("hh:ss:mm")) + ; + return convert_html_to_paragraph(t); + } + private static void add_header_footer(PageSetup ps, PdfDocument pdf, Document pdf_doc) + { + var pp = new Paragraph(); + int n = pdf.GetNumberOfPages(); + + var water_mark = new Paragraph("CellReport").SetFontColor(ColorConstants.LIGHT_GRAY) + .SetFontSize(40).SetOpacity(0.6f); + for (int page_idx = 1; page_idx <= n; page_idx++) + { + //pdf_doc.ShowTextAligned(water_mark, ps.pageSize_Width / 2, ps.pageSize_Height / 2, page_idx, TextAlignment.CENTER, + // VerticalAlignment.MIDDLE, 120); + + if (!String.IsNullOrEmpty(ps.footer_left)) + { + pp = replace_var_to_Paragraph(ps.footer_left, page_idx, n); + pdf_doc.ShowTextAligned(pp, ps.margin_footer, ps.margin_footer, page_idx, TextAlignment.LEFT, + VerticalAlignment.BOTTOM, 0);//footer left BOTTOM + } + + if (!String.IsNullOrEmpty(ps.footer_right)) + { + pp = replace_var_to_Paragraph(ps.footer_right, page_idx, n); + pdf_doc.ShowTextAligned(pp, + ps.pageSize_Width - ps.margin_footer, ps.margin_footer, page_idx, TextAlignment.RIGHT, + VerticalAlignment.BOTTOM, 0);//footer RIGHT BOTTOM + } + if (!String.IsNullOrEmpty(ps.header_left)) + { + pp = replace_var_to_Paragraph(ps.header_left, page_idx, n); + pdf_doc.ShowTextAligned(pp, + ps.margin_footer, ps.pageSize_Height - ps.margin_footer, page_idx, TextAlignment.LEFT, + VerticalAlignment.TOP, 0);//header left top + } + if (!String.IsNullOrEmpty(ps.header_right)) + { + pp = replace_var_to_Paragraph(ps.header_right, page_idx, n); + pdf_doc.ShowTextAligned(pp, + ps.pageSize_Width - ps.margin_footer, ps.pageSize_Height - ps.margin_footer, page_idx, TextAlignment.RIGHT, + VerticalAlignment.TOP, 0);//header right TOP + } + if (!String.IsNullOrEmpty(ps.header_center)) + { + pp = replace_var_to_Paragraph(ps.header_center, page_idx, n); + pdf_doc.ShowTextAligned(pp, + ps.pageSize_Width / 2, ps.pageSize_Height - ps.margin_footer, page_idx, TextAlignment.CENTER, + VerticalAlignment.TOP, 0); //header CENTER + } + if (!String.IsNullOrEmpty(ps.footer_center)) + { + pp = replace_var_to_Paragraph(ps.footer_center, page_idx, n); + pdf_doc.ShowTextAligned(pp, + ps.pageSize_Width / 2, ps.margin_footer, page_idx, TextAlignment.CENTER, + VerticalAlignment.BOTTOM, 0);//footer CENTER + } + } + } + + private static Table addTable(ReportGridJSON rg, List row_list, List col_list) + { + List tableBitFlag = new(); + for (int i = 0; i < rg.tableData.Length; i++) + { + tableBitFlag.Add(new BitArray(rg.columnlenArr.Count)); + } + var cols = new List(); + foreach (var one in col_list) + { + cols.Add(rg.cols[one]); + } + float tbl_height = 0; + foreach (var one in row_list) + { + tbl_height += rg.GetRowHeight(one); + } + var pdf_table = new Table(cols.ToArray())// 设置表格列数 + .SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER); + + foreach (var rowNo in row_list) + { + var row = rg.tableData[rowNo]; + pdf_table.StartNewRow(); + foreach (var colNo in col_list) + { + if (colNo >= row.Length) + continue; + var cell_value = row[colNo]; + if (colNo >= rg.columnlenArr.Count) + { + break; + } + if (tableBitFlag[rowNo].Get(colNo)) + { + continue; + } + tableBitFlag[rowNo].Set(colNo, true); + var max_height = rg.GetRowHeight(rowNo); + + var max_width = rg.columnlenArr[colNo]; + var r_c = rg.find_config_merge(rowNo, colNo); + int rowSpan = 1, colSpan = 1; + Cell pdf_cell; + bool is_lastcol_split_cell = false; + bool is_lastrow_split_cell = false; + if (r_c == null) + { + pdf_cell = new Cell(); + } + else + { + if (r_c.rs > 1) rowSpan = r_c.rs; + if (r_c.cs > 1) colSpan = r_c.cs; + if (colNo + colSpan - 1 > col_list.Last()) + { + colSpan = col_list.Last() - colNo + 1; + is_lastcol_split_cell = true; + rg.insert_merge(rowNo, colNo + colSpan, rowSpan, r_c.cs - colSpan); + } + if (rowNo + rowSpan - 1 > row_list.Last()) + { + rowSpan = row_list.Last() - rowNo + 1; + is_lastrow_split_cell = true; + rg.insert_merge(rowNo + rowSpan, colNo, r_c.rs - rowSpan, colSpan); + } + pdf_cell = new Cell(rowSpan, colSpan); + max_width = 0; + for (var ci = 0; ci < colSpan; ci++) + { + max_width += rg.columnlenArr[colNo + ci]; + } + max_height = 0; + for (var ri = 0; ri < rowSpan; ri++) + { + max_height += rg.GetRowHeight(rowNo + ri); + for (var ci = 0; ci < colSpan; ci++) + { + tableBitFlag[r_c.r + ri]?.Set(r_c.c + ci, true); + } + } + } + pdf_cell.SetBorder(Border.NO_BORDER); + foreach (var one_style in rg.find_style(rowNo, colNo)) + { + switch (one_style.Key) + { + case "background-color": + pdf_cell.SetBackgroundColor(new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(one_style.Value))); + break; + case "color": + pdf_cell.SetFontColor(new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(one_style.Value))); + break; + case "font-family": + //ret["font-family"] = one_pair[1]; + break; + case "FONT-SIZE": + pdf_cell.SetFontSize(float.Parse(one_style.Value)); + break; + case "font-weight": + pdf_cell.SetBold(); + break; + case "BORDER-LEFT": + var border_style = (one_style.Value as String).Split(); + pdf_cell.SetBorderLeft(new SolidBorder( + new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(border_style[1])) + , float.Parse(border_style[0]))); + break; + case "BORDER-RIGHT": + if (!is_lastcol_split_cell) + { + border_style = (one_style.Value as String).Split(); + pdf_cell.SetBorderRight(new SolidBorder( + new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(border_style[1])) + , float.Parse(border_style[0]))); + } + break; + case "BORDER-TOP": + border_style = (one_style.Value as String).Split(); + pdf_cell.SetBorderTop(new SolidBorder( + new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(border_style[1])) + , float.Parse(border_style[0]))); + break; + case "BORDER-BOTTOM": + if (!is_lastrow_split_cell) + { + border_style = (one_style.Value as String).Split(); + pdf_cell.SetBorderBottom(new SolidBorder( + new DeviceRgb(System.Drawing.ColorTranslator.FromHtml(border_style[1])) + , float.Parse(border_style[0]))); + } + break; + case "vertical-align": + switch (one_style.Value.ToString().ToUpper()) + { + case "TOP": + pdf_cell.SetVerticalAlignment(VerticalAlignment.TOP); + break; + case "BOTTOM": + pdf_cell.SetVerticalAlignment(VerticalAlignment.BOTTOM); + break; + default: + pdf_cell.SetVerticalAlignment(VerticalAlignment.MIDDLE); + break; + } + + break; + case "text-align": + switch (one_style.Value.ToString().ToUpper()) + { + case "LEFT": + pdf_cell.SetTextAlignment(TextAlignment.LEFT); + break; + case "RIGHT": + pdf_cell.SetTextAlignment(TextAlignment.RIGHT); + break; + default: + pdf_cell.SetTextAlignment(TextAlignment.CENTER); + break; + } + + break; + } + } + int deta = 0; + IBlockElement cur_pp = null; + var cur_str = cell_value == null ? "" : cell_value.ToString(); + if (cur_str.StartsWith("<")) + { + var t_list = HtmlConverter.ConvertToElements($"
{cur_str}
", converterProperties); + if (t_list.Count == 1 && t_list[0] is IBlockElement) + cur_pp = t_list[0] as IBlockElement; + else + cur_pp = new Paragraph(cur_str); + } + else + { + cur_pp = new Paragraph(cur_str); + } + pdf_cell.Add(cur_pp) + //replace_var_to_Paragraph(cell_value.ToString(),0,0) + .SetMinWidth(max_width - deta).SetMaxWidth(max_width - deta) + .SetMinHeight(max_height - deta).SetMaxHeight(max_height - deta) + .SetPadding(0)// 不设置为0 ,将导致高度和设置的不同 缺省padding =2 + //.SetMargin(2) + + ; + + pdf_table.AddCell(pdf_cell); + } + } + + return pdf_table; + } + } +} diff --git a/end/reportWeb/Controllers/UserController.cs b/end/reportWeb/Controllers/UserController.cs index 45417df..e065f46 100644 --- a/end/reportWeb/Controllers/UserController.cs +++ b/end/reportWeb/Controllers/UserController.cs @@ -72,12 +72,12 @@ public IActionResult test_login(String login_script,string test_user, string tes ef.addVariable("__env__", new Env()); ef.addVariable("userid", test_user); ef.addVariable("password", test_password); - var result = ef.addNewScopeForScript(login_script) as IDictionary; - if (result == null) - return Json(new { errcode = 1, message = "测试失败", result = "不是正常返回对象,请仔细看说明要求" }, json_option); + var result = ef.addNewScopeForScript(login_script) as IDictionary; + if(result == null) + return Json(new { errcode = 1, message = "测试失败", result="不是正常返回对象,请仔细看说明要求" }, json_option); if (!"0".Equals(result["errcode"]?.ToString())) { - return Json(new { errcode = 0, message = "测试成功", result }, json_option); + return Json(new { errcode = 1, message = "测试成功", result }, json_option); } return Json(new { errcode = 0, message = "测试成功", result }, json_option); } diff --git a/end/reportWeb/Startup.cs b/end/reportWeb/Startup.cs index c03017a..6ab65ee 100644 --- a/end/reportWeb/Startup.cs +++ b/end/reportWeb/Startup.cs @@ -42,7 +42,7 @@ namespace reportWeb { - public class Startup + public class Startup { public Startup(IConfiguration configuration) { @@ -50,11 +50,16 @@ public Startup(IConfiguration configuration) } public IConfiguration Configuration { get; } - + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - + try + {//֣ᱨӰ + iText.Kernel.Font.PdfFontFactory.RegisterSystemDirectories(); + } + catch { + } //services.AddSingleton(HtmlEncoder.Create(System.Text.Unicode.UnicodeRanges.All)); CellReport.core.expr.ExprHelper.buildFuncMap(); //CellReport.core.expr.ExprHelper.AddFunc(typeof(CellReport.function.Func_md5)); @@ -81,16 +86,16 @@ public void ConfigureServices(IServiceCollection services) })*/ .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, option => { - option.SaveToken = true; + option.SaveToken = true; option.Events = new JwtBearerEvents() { OnMessageReceived = context => { - if(context.Request.Headers["Authorization"].ToString()=="" && context.Request.Cookies["access_token"]!=null) - context.Token = context.Request.Cookies["access_token"]; + if (context.Request.Headers["Authorization"].ToString() == "" && context.Request.Cookies["access_token"] != null) + context.Token = context.Request.Cookies["access_token"]; return Task.CompletedTask; }, - OnChallenge= context => + OnChallenge = context => { context.HandleResponse(); context.Response.WriteAsJsonAsync(new { code = -1, message = "token" }); @@ -98,7 +103,7 @@ public void ConfigureServices(IServiceCollection services) }, OnAuthenticationFailed = context => { - + //ASP.NET Core Web Api֮JWTˢToken() //https://blog.csdn.net/weixin_30483013/article/details/99642627?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase // ڣ<Ƿ>ӵͷϢ @@ -113,8 +118,21 @@ public void ConfigureServices(IServiceCollection services) raw_token = raw_token.Substring("Bearer ".Length); var tokenHandler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var token = tokenHandler.ReadJwtToken(raw_token); - if("refresh" != token.Claims.FirstOrDefault(x => x.Type == "token_type")?.Value) - context.Response.Headers.Add("Token-Expired", "true"); + //var jwtConfig = context.HttpContext.RequestServices.GetService(); + //tokenHandler.ValidateToken(raw_token, new TokenValidationParameters + //{ + // ValidIssuer = jwtConfig.Issuer, + // ValidAudience = jwtConfig.Audience, + // ValidateAudience = false, + // ValidateIssuer = false, + // ValidateLifetime = true,//jwtConfig.ValidateLifetime, + // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SigningKey)), + // //ʱ䣬ܵЧʱʱjwtĹʱ + // ClockSkew = TimeSpan.FromSeconds(0) + //}, out SecurityToken validatedToken); + + if ("refresh" != token.Claims.FirstOrDefault(x => x.Type == "token_type")?.Value) + context.Response.Headers.Add("token-expired", "true"); } return Task.CompletedTask; }, @@ -127,14 +145,14 @@ public void ConfigureServices(IServiceCollection services) { ValidIssuer = jwtConfig.Issuer, ValidAudience = jwtConfig.Audience, - ValidateAudience=false, - ValidateIssuer = false, + ValidateAudience = false, + ValidateIssuer = false, ValidateLifetime = true,//jwtConfig.ValidateLifetime, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SigningKey)), //ʱ䣬ܵЧʱʱjwtĹʱ ClockSkew = TimeSpan.FromSeconds(0) }; - }); + }); //================================ // If using Kestrel: services.Configure(options => @@ -143,7 +161,7 @@ public void ConfigureServices(IServiceCollection services) }); services.AddScoped(); services.AddSingleton(jwtConfig); - + // If using IIS: services.Configure(options => { @@ -161,10 +179,10 @@ public void ConfigureServices(IServiceCollection services) services.AddCors(op => { op.AddPolicy("CorsTest", set => { - set.SetIsOriginAllowed(origin => true) - .AllowAnyHeader() - .AllowAnyMethod() - .AllowCredentials();//Ҫģûͻп + set.SetIsOriginAllowed(origin => true) + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials();//Ҫģûͻп }); }); services.AddSignalR(); @@ -178,7 +196,7 @@ public void ConfigureServices(IServiceCollection services) services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection")); CellReport.Redis_Cache.redis_str = Configuration["redis_str"]; - if(!String.IsNullOrEmpty( CellReport.Redis_Cache.redis_str )) + if (!String.IsNullOrEmpty(CellReport.Redis_Cache.redis_str)) { CSRedisClient redisClient = new CSRedisClient(CellReport.Redis_Cache.redis_str); RedisHelper.Initialization(redisClient); @@ -186,18 +204,17 @@ public void ConfigureServices(IServiceCollection services) DbProviderFactories.RegisterFactory("Microsoft.Data.Sqlite", SqliteFactory.Instance); foreach (var one in Configuration.GetSection("DbProviderFactories").Get()) { - //var ass = System.Reflection.Assembly.LoadFile(Path.Combine((new DirectoryInfo(Environment.ProcessPath)).Parent.FullName, one.DllName + ".dll")); - var ass = System.Reflection.Assembly.Load( one.DllName); + var ass = System.Reflection.Assembly.Load(one.DllName); DbProviderFactory f = ass.GetType(one.FactoryClass).GetField(one.InstanceName).GetValue(null) as DbProviderFactory; - DbProviderFactories.RegisterFactory(one.Name, f ); - + DbProviderFactories.RegisterFactory(one.Name, f); + } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbContext _reportDbContext) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ReportDbContext _reportDbContext) { - + _reportDbContext.Database.EnsureCreated();//ݿⲻڵĻԶ if (_reportDbContext.Rpt_group.Count() == 0) { @@ -220,8 +237,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC default_page = "default", name = "", report_path = main_path, - db_connection_list=new List() - { + db_connection_list = new List() + { new Rpt_db_connection() { conn_str=$"Data Source={main_path}/test.db", db_type="Microsoft.Data.Sqlite", name="testsqlite"}, } }); @@ -235,6 +252,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC }); _reportDbContext.SaveChanges(); } + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); @@ -280,11 +298,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC }); //app.UseHttpsRedirection(); app.UseStaticFiles(); - + app.Use(next => context => { var cur_path = context.Request.Path.Value; - if (cur_path.Contains("/design/")) + if (cur_path.Contains("/design")) { cur_path = cur_path.Substring(cur_path.IndexOf("/design/")); } @@ -294,19 +312,19 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC } var seg_arr = cur_path.Split(":"); string grp = "default"; - if (seg_arr.Length>=2) + if (seg_arr.Length >= 2) { - grp=seg_arr[1]; + grp = seg_arr[1]; } - + var scopedObj = context.RequestServices.GetService(); //scopedObj.rpt_group = context.RequestServices.GetService().findGroupById(grp); - scopedObj.rpt_group = context.RequestServices.GetService ().Rpt_group.AsNoTracking() - .Include(x=>x.db_connection_list) + scopedObj.rpt_group = context.RequestServices.GetService().Rpt_group.AsNoTracking() + .Include(x => x.db_connection_list) .Where(i => i.Id == grp) .FirstOrDefault(); scopedObj.WebHostEnvironment = env; - + context.Request.Path = seg_arr[0]; if (context.Request.Path == "/run") { @@ -316,7 +334,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC context.Response.ContentType = "application/json"; return context.Response.WriteAsync("{ \"errcode\":1, \"message\":\"grpûж\" }"); } - var rn=context.Request.Query["reportName"]; + var rn = context.Request.Query["reportName"]; if (rn.Count == 1) { context.Request.Path = "/" + scopedObj.rpt_group.getPageNameByReportName(rn[0]); @@ -334,13 +352,13 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC app.UseAuthentication();//֤(Authentication) app.UseAuthorization(); //Ȩ (Authorization) - app.UseSession(); + app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapHub("/chathub"); - endpoints.MapControllerRoute(name: "default",pattern: "{controller=user}/{action=Index}/{id?}"); + endpoints.MapControllerRoute(name: "default", pattern: "{controller=user}/{action=Index}/{id?}"); //endpoints.MapDynamicPageRoute("{page}/{**grp}"); //endpoints.MapDynamicControllerRoute("{area}/{controller=Home}/{action=Index}/{id:int?}"); //endpoints.Map(RoutePatternFactory.Parse("/run/{act}/{grp}/{a0}/{a1}"), rpt_execute); @@ -354,7 +372,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ReportDbC { var m = MessageQueueBlock.Take();//Client(m.ConnectionId) if (m.ConnectionId != null) - await m.hubContext.Clients.Client(m.ConnectionId)?.SendAsync("ReceiveMessage",m.ConnectionId,m.Body); + await m.hubContext.Clients.Client(m.ConnectionId)?.SendAsync("ReceiveMessage", m.ConnectionId, m.Body); } catch (Exception ex) { diff --git a/end/reportWeb/reportWeb.csproj b/end/reportWeb/reportWeb.csproj index 854d6b0..8a6e751 100644 --- a/end/reportWeb/reportWeb.csproj +++ b/end/reportWeb/reportWeb.csproj @@ -12,8 +12,10 @@ - + + + diff --git a/front/src/App.vue b/front/src/App.vue index 4351a41..1e8b969 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -21,6 +21,21 @@ export default { height: 100%; overflow: hidden; } +.el-button{ + padding: 5px 10px !important; +} + +.el-button.is-circle{ + padding:7px !important; +} + +.el-dialog__headerbtn{ + top:10px !important; +} + +.el-tabs__item{ + font-size: 12px !important; +} .cr_run_title { line-height: 28px; border-bottom: 1px solid gray;font-weight: 500; margin-bottom: 5px; } .vue-codemirror{border: 1px solid black;} .el-table td, .el-table th { diff --git a/front/src/views/rpt_design/api/report_api.js b/front/src/views/rpt_design/api/report_api.js index 878227d..ad7cf29 100644 --- a/front/src/views/rpt_design/api/report_api.js +++ b/front/src/views/rpt_design/api/report_api.js @@ -53,8 +53,6 @@ export function open_one(reportName,zb_dict,zb_param) { let arr=reportName.split(":") let grpId,reportFilePath let data=new FormData(); - //let test_zb_data={"b": "{\"columns\":[\"机构名称\",\"报案件数\",\"发起探访件数\",\"完成探访件数\",\"结案件数\",\"结案金额\",\"机构号\"],\"index\":[0],\"data\":[[\"合计\",322,314,181,230,177166.11,\"合计\"]]}", "a": "{\"columns\":[\"机构名称\",\"报案件数\",\"发起探访件数\",\"完成探访件数\",\"结案件数\",\"结案金额\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\"data\":[[\"开封\",12,3,4,27,15384.72],[\"洛阳\",61,64,48,44,14720.14],[\"平顶山\",27,26,35,21,14921.66],[\"安阳\",7,9,12,9,11029.37],[\"鹤壁\",18,25,11,8,8120.17],[\"新乡\",6,3,2,4,15728.18],[\"焦作\",26,29,31,35,16406.01],[\"濮阳\",27,17,8,11,12072.37],[\"许昌\",30,67,4,16,6619.2],[\"漯河\",1,0,0,1,687.82],[\"三门峡\",21,20,10,11,9123.22],[\"商丘\",21,11,2,8,11850.16],[\"周口\",7,1,4,5,6379.94],[\"驻马店\",3,0,0,0,0.0],[\"南阳\",32,36,8,15,20990.96],[\"信阳\",23,3,2,15,13132.19]]}"} - //let test_param={} if(zb_dict) data.append('zb_dict_str',JSON.stringify(zb_dict)) if(zb_param) @@ -184,7 +182,7 @@ export async function preview_one(_this,createFormParam=false,query_data={},para data.append("reportName", _this.context.report.reportName) data.append("_createFormParam", createFormParam??false) if(param_name!=null) - data.append("_param_name", param_name) + data.append("_param_name_", param_name) Object.entries(query_data).forEach(kv=>{ data.append(kv[0], kv[1]) }) @@ -279,7 +277,7 @@ export async function preview_one(_this,createFormParam=false,query_data={},para }) } const loading_conf={type: 'loading',options: {fullscreen: true,lock: true,text: '正在载入...',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.8)'}} -export function run_one(_this,reportFilePath,query,query_data={},_param_name=null) { +export function run_one(_this,reportFilePath,query,query_data={},_param_name_=null) { let data=new FormData(); Object.entries(query_data).forEach(kv=>{ data.append(kv[0], kv[1]) @@ -287,8 +285,8 @@ export function run_one(_this,reportFilePath,query,query_data={},_param_name=nul let _fresh_ds=query_data._fresh_ds loading.show(loading_conf) data.append("reportName", reportFilePath) - if(_param_name!=null) - data.append("_param_name_", _param_name) + if(_param_name_!=null) + data.append("_param_name_", _param_name_) let url if(window.location.pathname.endsWith("run.html")) _this.in_exec_url.run_url=`${baseUrl}/report5/run${_this.grpId==0?"":":"+_this.grpId}?`+query @@ -323,7 +321,7 @@ export function run_one(_this,reportFilePath,query,query_data={},_param_name=nul _this.$set(_this.queryForm_show,ele.name,false) }) - if(_param_name!=null){ + if(_param_name_!=null){ _this.result.dataSet=response_data.dataSet _this.result.form=response_data.form loading.hide(loading_conf) diff --git a/front/src/views/rpt_design/datasetManger2.vue b/front/src/views/rpt_design/datasetManger2.vue index b99351b..d28841f 100644 --- a/front/src/views/rpt_design/datasetManger2.vue +++ b/front/src/views/rpt_design/datasetManger2.vue @@ -101,7 +101,7 @@ diff --git a/front/src/views/rpt_design/design_index.vue b/front/src/views/rpt_design/design_index.vue index 4d1938a..5ad861e 100644 --- a/front/src/views/rpt_design/design_index.vue +++ b/front/src/views/rpt_design/design_index.vue @@ -37,23 +37,26 @@ - - 保存 - 预览 - 重载 - 参数 - 数据 - 设置 - 向导 - 组件 -
+ + + 保存 + 预览 + 重载 + 参数 + 数据 + 设置 + 向导 + 组件 + + 运行 + +
+ -
- - 运行 - +
-
    +
    • - 扩展方向 + @@ -102,9 +105,8 @@ ]" style="display: flex;padding-bottom: 10px;" :key="item.display" > + - {{item.display}} - {{ cur_cell.cr[item.val] }} @@ -760,10 +762,10 @@ export default { if(this.setCellFromAPI){ return } - let grid= this.report.AllGrids.grid.find(a=>a._name==this.sheet_window.gridName) + let grid= this.report.AllGrids.grid.find(a=>a._name==_this.sheet_window.gridName) function add_rc(val){ - if(this.sheet_window.luckysheet.is_in_simapleGuid){ - delete this.sheet_window.luckysheet.is_in_simapleGuid + if(_this.sheet_window.luckysheet.is_in_simapleGuid){ + delete _this.sheet_window.luckysheet.is_in_simapleGuid return } //删除被lucky添加的无用单元格 @@ -836,7 +838,8 @@ export default { } } } - } + }//end function add_rc + this.setCellFromAPI = true; try{ add_rc(val) @@ -982,6 +985,19 @@ export default { save_one(this.report) //console.info(x2jsone.js2xml({report:this.report})) }, + run_report(url){ + // console.log(url) + this.save_fix() + this.save_layout(this.layout_mode) + save_one(this.report) + let newA = document.createElement('a'); + newA.target = '_blank'; + newA.href = url; + document.body.appendChild(newA); + newA.click(); + document.body.removeChild(newA); + //console.info(x2jsone.js2xml({report:this.report})) + }, refresh_setting(){ let _this=this let old_widgetForm=_this.widgetForm diff --git a/front/src/views/rpt_design/element/WidgetFormItem.vue b/front/src/views/rpt_design/element/WidgetFormItem.vue index c0190f1..0c05f27 100644 --- a/front/src/views/rpt_design/element/WidgetFormItem.vue +++ b/front/src/views/rpt_design/element/WidgetFormItem.vue @@ -8,7 +8,7 @@ {{self.label}} - - \ No newline at end of file +/* .design-list .el-button{ + padding:7px !important; +} */ + + diff --git a/front/src/views/rpt_design/simpleGuide.vue b/front/src/views/rpt_design/simpleGuide.vue index 354aceb..1043cb4 100644 --- a/front/src/views/rpt_design/simpleGuide.vue +++ b/front/src/views/rpt_design/simpleGuide.vue @@ -19,8 +19,8 @@
      多数据集是否合并
      - - + +
      @@ -49,6 +49,7 @@ trigger="click"> group + select {{item.op?item.op:"选择"}}
    • @@ -95,6 +96,7 @@ trigger="click"> group + select {{item.op?item.op:"选择"}} @@ -129,6 +131,9 @@ trigger="click"> sum + max + min + avg {{item.op?item.op:"选择"}} @@ -239,8 +244,9 @@ export default { let expr='' let luckysheet=this.sheet_window.luckysheet - const {row_focus,column_focus}=luckysheet.getluckysheet_select_save()[0] - luckysheet.insertColumn(column_focus,{number:this.detail_fields.length}) + const {row_focus,column_focus}=luckysheet.getluckysheet_select_save()[0] + if(this.detail_fields.length>0) + luckysheet.insertColumn(column_focus,{number:this.detail_fields.length}) let data=luckysheet.getSheet(0).data if(this.col_union_chk) { expr='' @@ -254,18 +260,17 @@ export default { expr = "=union_set(" + expr + ")" else expr = "=" + expr - let mc={"r": row_focus+row, //主单元格的行号 + let cell_val= {v:expr,m:expr, + mc:{"r": row_focus+row, //主单元格的行号 "c": column_focus+ rowsGroupCount + col, //主单元格的列号 "rs": 1, //合并单元格占的行数 "cs": this.detail_fields.length //合并单元格占的列数 - } - if(this.detail_fields.length>1) - mc==undefined - data[row_focus+row][column_focus+ rowsGroupCount + col ] - = {v:expr,m:expr, - mc:mc, + }, cr:{"_displayValueExpr":"=@value","_valueExpr":expr,"_extendDirection":"column"}} - if(mc!=undefined){ + if(cell_val.mc.cs<=1) + delete cell_val.mc + data[row_focus+row][column_focus+ rowsGroupCount + col ]=cell_val + if(cell_val.mc!=undefined){ luckysheet.getSheet(0).config.merge[`${row_focus+row}_${column_focus+ rowsGroupCount + col}`]=mc for(let idx=1;idx < this.detail_fields.length ;idx++ ){ data[row_focus+row][column_focus+ rowsGroupCount + col + idx ]={ mc:{ "r": row_focus+row,"c": column_focus+ rowsGroupCount + col} } @@ -277,19 +282,18 @@ export default { expr='' this.col_grp_fields.forEach(one_col=>{ expr = `=${one_col.ds}.group(${one_col.ds}["${one_col.field}"])` - let mc={"r": row_focus+row, //主单元格的行号 + let cell_val={v:expr,m:expr, + mc:{"r": row_focus+row, //主单元格的行号 "c": column_focus+ rowsGroupCount + col, //主单元格的列号 "rs": 1, //合并单元格占的行数 "cs": this.detail_fields.length //合并单元格占的列数 - } - if(this.detail_fields.length>1) - mc==undefined - data[row_focus+row][column_focus+ rowsGroupCount + col] - ={v:expr,m:expr, - mc:mc, + }, cr:{"_displayValueExpr":"=@value","_valueExpr":expr,"_extendDirection":"column"}} - if(mc!=undefined){ - luckysheet.getSheet(0).config.merge[`${row_focus+row}_${column_focus+ rowsGroupCount + col}`]=mc + if(cell_val.mc.cs<=1) + delete cell_val.mc + data[row_focus+row][column_focus+ rowsGroupCount + col]=cell_val + if(cell_val.mc!=undefined){ + luckysheet.getSheet(0).config.merge[`${row_focus+row}_${column_focus+ rowsGroupCount + col}`]=cell_val.mc for(let idx=1;idx < this.detail_fields.length ;idx++ ){ data[row_focus+row][column_focus+ rowsGroupCount + col + idx ]={ mc:{ "r": row_focus+row,"c": column_focus+ rowsGroupCount + col} } } diff --git a/front/src/views/rpt_design/styles/index.scss b/front/src/views/rpt_design/styles/index.scss index f18dcb1..d6b1096 100644 --- a/front/src/views/rpt_design/styles/index.scss +++ b/front/src/views/rpt_design/styles/index.scss @@ -72,11 +72,7 @@ $primary-background-color: #ecf8ff; .form-designer { height: 100%; background: #fff; - outline: 1px solid #e4e7ed; - - - - + //outline: 1px solid #e4e7ed; .fields-list { padding: 10px 0; width: 100%; @@ -275,7 +271,7 @@ $primary-background-color: #ecf8ff; &__body { min-height: 20px; height: 100%; - outline: 1px dashed #ccc; + //outline: 1px dashed #ccc; outline-offset: -1px; overflow: hidden; padding-bottom: 1px; diff --git a/front/src/views/rpt_design/widgetManger.vue b/front/src/views/rpt_design/widgetManger.vue index a7b659c..bb038fb 100644 --- a/front/src/views/rpt_design/widgetManger.vue +++ b/front/src/views/rpt_design/widgetManger.vue @@ -1,7 +1,7 @@