راه اندازی StimulSoft Report در ASP.NET MVC
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: یازده دقیقه

یکی از ارکان لاینفک سیستم‌های سازمانی در هر پلتفرمی، چه وب و چه دسکتاپ و ... گزارش گیری از اطلاعات موجود و جزو ساختار حیاتی آن است. از آنجا که حتی ممکن است این گزارشات در هر دوره نیاز به تغییرات داشته باشند و گزارش‌های پویایی باشند؛ این نیاز احساس می‌شود که از یک برنامه گزارش ساز مناسب بهره ببریم. یکی از گزارش سازهای محبوب به خصوص در ایران که حتی نماینده رسمی آن هم در ایران وجود دارد، گزارش ساز StimulSoft Report است.

دارا بودن امکانات بسیار قدرتمند و پشتیبانی از محیط فارسی و همچنین پشتیبانی آن‌ها جهت پاسخگویی به سوالات، چه از طریق ایمیل یا چت، از نقاط قوت این ابزار به شمار می‌روند. در جدول مقایسات می‌توانید تفاوت نسخه‌های موجود این گزارش ساز را مشاهده کنید. برای استفاده در MVC از نسخه وب آن استفاده میکنیم.

در این مقاله قصد داریم با نحوه راه ندازی این ابزار در وب (MVC) آشنا شویم که شامل مباحث زیر می‌شود:
  1. استفاده از EF به عنوان منبع داده و ارسال آن‌ها به سمت گزارش ساز
  2. نحوه طراحی فایل MRT و بایند کردن داده‌های اطلاعاتی و ایجاد جدول
  3. استفاده از امکانات فایل خروجی ، چاپ و پیش نمایش و...
  4. بررسی Direction جهت استفاده در محیط‌های فارسی زبان
  5. نحوه ارسال اطلاعات بین دو اکشن متفاوت


طراحی فایل MRT

فایل MRT در واقع یک قالب (Template) خالی از مقادیر متغیر است که در StimulSoft Studio به طراحی آن میپردازیم و در برنامه خود، این مقادیر متغیر را با اطلاعات دلخواه خود جایگزین می‌کنیم. تصویر زیر یک نمونه از یک گزارش خالی است که ابتدا آن را طراحی کرده و سپس در برنامه آن را مورد استفاده قرار می‌دهیم:

برای اینکه فایل MRT بتواند دیتاهای لازمی را که به آن پاس میدهیم، بخواند و در جای مشخص شده قرار بدهد، باید یک BussinessObject برای آن ایجاد کنیم. بعد از اینکه یک گزارش جدید ایجاد کردید، در سمت راست به قسمت Dictionary بروید و در قسمت BussinessObject گزینه NewBussinessObject را انتخاب کنید. یک نام و نام مستعار که عموما هم یکی است، برای آن انتخاب کنید. در زیر همان پنجره شما می‌توانید ستون‌های اطلاعاتی خود را تعریف کنید. در اینجا من میخواهم اطلاعات یک راننده را به همراه خودروی وی، نشان دهم. برای همین، من دو موجودیت راننده و خودروی راننده را دارم. پس اسم Business Object را DriverReport میگذارم و ستون‌های اطلاعاتی فقط راننده (بدون در نظر گرفتن خودروی وی) را وارد میکنم.

در همین کادر بالا شما میتوانید تصیم بگیرید که آیا میخواهید اطلاعات خودرو را به همراه دیگرستون‌های اطلاعاتی راننده، ایجاد کنید یا اینکه برای خودرو یک نوع مجزا انتخاب کنید. اگر تنها یک خودرو برای راننده باشد، شاید راحت‌تر باشید همانند اطلاعات راننده با آن رفتار کنید. ولی اگر مثلا بخواهید خودروی‌های گذشته راننده را هم جز لیست داشته باشید، بهتر است یک  Business Object جدید متعلق و زیر مجموعه Business Object راننده ایجاد کنید. در اینجا چون تنها یک خودرو است، من آن اطلاعات آن را به همراه راننده، ارسال میکنم. شکل زیر ساختار درختی از گزارش بالاست:

شکل زیر هم یک ساختار دیگر از یک گزارش است که شامل Business object‌های مختلف می‌شود: 

سپس همین فیلدها را به سمت صفحه خالی بکشانید. با دو بار کلیک روی فیلدهای قرار گرفته در صفحه، با نحوه بایند کردن مقادیر آشنا می‌شوید؛ هر فیلدی که قرار است دیتای آن بایند شود، باید به شکل زیر در بخش Expression پنجره باز شده، نوشته شود:

{driverReport.LastName}
در صورتیکه قرار است Business Object به شکل یک لیست ارسال شود؛ مثلا لیست رانندگان یا حتی لیست خودروهایی که یک راننده از گذشته تا کنون داشته است، می‌توانید به جای درگ کردن فیلد به درون صفحه، خود Business Object را درگ کنید تا از روی آن یک جدول درست شود و با ارسال یک لیست به سمت آن و به ازای هر آیتم از این لیست یک سطر داشته باشید.

در دیکشنری همچنین انواع دیگری از فیلدها نیز به چشم میخورد:
متغیرها: این نوع فیلد یک متغیر است که به طور جداگانه میتواند مقداردهی شود و از آن بیشتر برای ارسال داده‌های تکی چون تصاویر، تاریخ شمسی و ... میتوان استفاده کرد.
متغیرهای سیستمی: این نوع متغیرها توسط خود گزارش ساز به طور مستقیم پر می‌شوند که شامل شماره صفحه، تاریخ و زمان، تعداد صفحات، مقادیر دو ارزشی (آیا صفحه آخر گزارش است؟) و ... می‌شود.
توابع: گزارش ساز شامل یک سری توابع آماده برای اعمال تغییرات بر روی داده‌ها میباشد که در دسته‌های مختلفی چون کار با رشته‌ها، زمان، ریاضیات و... قرار گرفته‌اند.
بعد از تکمیل آن، فایل MRT را ذخیره و در یک دایرکتوری در ساختار پروژه قرار دهید.

راه اندازی گزارش ساز در ASP.Net MVC

اولین کاری که می‌کنیم، ورود سه dll اصلی به پروژه است:

Stimulate.Base

Stimulate.Report

Stimulate.Report.MVC

در مرحله بعد یک متد ساخته و یک ویوو را برای صفحه گزارش گیری ایجاد می‌کنیم:

public ActionResult Report(int id)
{
   return View();
}
در ویوی مربوطه کدهای زیر را اضافه می‌کنیم:
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions()
{
   
    Localization = "~/content/reports/fa.xml",
    Actions =
        {
        
            GetReportSnapshot = "LoadReportSnapshot",
            ViewerEvent = "ViewerEvent",
            ExportReport = "ExportReport",
            PrintReport = "PrintReport",
        }
 }

در نسخه‌های دو سال اخیر، استفاده از این Helper تفاوت‌هایی در نحوه استفاده از خصوصیت‌های آن کرده است. در این روش جدید، پراپرتی‌ها دسته بندی شده و برای دسترسی به هر کدام باید به بخش آن مراجعه کنید؛ مثلا پراپرتی‌های Action، در دسته Actions قرار گرفته‌اند یا خصوصیت‌های ظاهری در دسته Appearance، یا گزینه‌های مرتبط با خروجی گرفتن‌ها، در دسته Export قرار گرفته‌اند و الی آخر که در نسخه‌های پیشین، کد بالا را به شکل زیر،  با پیشوند نام دسته می‌نوشتیم:
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions()
{
   
    Localization = "~/content/reports/fa.xml",
            ActionGetReportSnapshot = "LoadReportSnapshot",
            ActionViewerEvent = "ViewerEvent",
            ActionExportReport = "ExportReport",
            ActionPrintReport = "PrintReport",
            
}
خصوصیت GetReportSnapshot نام یک اکشن متد است که کار ارسال دیتا را به گزارش ساز، انجام میدهد. باقی خصوصیت‌ها را در ادامه بررسی میکنیم. پس متد LoadReportSnapshot را ایجاد می‌کنم و کدهای زیر را در ادامه آن می‌نویسیم:

بعد از آن لازم است دیتا‌ها را از طریق EF خوانده و به یک مدل جدید که بر اساس اطلاعات گزارش شماست و قرار است گزارش شما این پراپرتی‌ها را بشناسد، به طور دستی یا با استفاده یک کتابخانه mapping مثل automapper انتقال دهید. یا حتی می‌توانید مانند کد زیر از ساختاری ناشناس استفاده کنید. در کد زیر، من به صورت تمرینی اطلاعات یک راننده و خودروی او را انتقال میدهم:
var driver = new
            {
                FirstName = "علی",
                LastName = "یگانه مقدم",
                NationalCode = "12500000000",
                FatherName = "حسین",
                Model = "نام خودرو",
                MotorNumber = 415244,
                ProductionYear = 1394,
                Capacity = 4
                
};
اگر اطلاعات خودرو را هم به صورت مجزا BussinessObject ساخته‌اید باید آن را به شکل زیر تعریف کنید ( با فرض اینکه نام BussinessObject در گزارش، با نام car تعریف شده باشد):
var driver = new
            {
                FirstName = "علی",
                LastName = "یگانه مقدم",
                NationalCode = "12500000000",
                FatherName = "حسین",
                car = new
                {
                    Model = "نام خودرو",
                    MotorNumber = 415244,
                    ProductionYear = 1394,
                    Capacity = 4
                }
};
بعد از اینکه دیتاهای لازم را بر اساس فرمت دلخواه خود آماده کردیم، باید آن‌ها را به سمت گزارش ساز ارسال کنیم:
var report = new StiReport();
            report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
            report.RegBusinessObject("driverReport", driver);
            report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date));
در مرحله اول یک وهله از شیء StiReport را می‌سازیم و فایل گزارشی را که در مرحله قبل ساختیم، به آن معرفی میکنیم. سپس داده‌های لازم را به آن انتقال می‌دهیم. پارامتر اول نام BussinessObject اصلی یعنی driverReport را وارد می‌کنیم و پارامتر دوم هم، همان اطلاعات گزارش است. خط بعدی هم یک متغیر است که من در گزارش تعریف کرده‌ام و در اینجا آن را با تاریخ شمسی امروز پر میکنم. توجه داشته باشید که انتقال اطلاعات حتما باید بعد از استفاده از متد Load باشد؛ در غیر اینصورت انتقالی انجام نخواهد شد. اینکه صرفا شما وهله‌ای از شیء StiReport بسازید و مقادیر را بدون ترتیب پر کنید، کفایت نمی‌کند. یعنی ترتیب زیر یک ترتیب کاملا اشتباه است:
var report = new StiReport();
            report.RegBusinessObject("driverReport", driver);
            report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date));
           report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
چیزی که بعدا در خروجی می‌بینید، یک صفحه گزارش بدون مقدار است.
پس کد کامل ما برای ایجاد یک گزارش به شکل زیر می‌شود:
 public ActionResult LoadReportSnapshot()
{
  var driver = new
            {
                FirstName = "علی",
                LastName = "یگانه مقدم",
                NationalCode = "12500000000",
                FatherName = "حسین",
                Model = "نام خودرو",
                MotorNumber = 415244,
                ProductionYear = 1394,
                Capacity = 4

            };

            var report = new StiReport();
            report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
            report.RegBusinessObject("driverReport", driver);
            report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date));
return StiMvcViewer.GetReportSnapshotResult(HttpContext, report);
}
همه خطوط، همان قبلی هاست که بررسی کردیم؛ بجز خط آخر که یک ActionResult اختصاصی است که در آن نحوه انتقال اطلاعات به گزارش ساز پیاده سازی شده است و تنها کاری که باید بکنیم این است که شیء گزارش ایجاد شده در بالا را به آن پاس دهیم.

اگر دوباره در ویو مربوطه، به سراغ helper برویم می‌بینیم که سه اکشن متد دیگر وجود دارند که در زیر، به ترتیب با نحوه کار آن‌ها و کد اکشن متد آن‌ها اشاره میکنیم:
Viewer Events : این اکشن متد که تنها یک خط ActionResult استاتیک را فراخوانی می‌کند، جهت مدیریت رویدادهای گزارش چون: زوم، صفحه بندی گزارش، خروجی‌ها و چاپ می‌باشد و وجود آن در گزارش از الزامات است.
 public virtual ActionResult ViewerEvent()
 {
            return StiMvcViewer.ViewerEventResult();
 }

PrintReport: برای مدیریت و ارسال گزارشات به دستگاه چاپ می‌باشد. این اطلاعات از طریق شی HttpContext به سمت اکشن متد ارسال شده و توسط PrintReportResult آن را دریافت می‌کند.
public virtual ActionResult PrintReport()
        {
            return StiMvcViewer.PrintReportResult(this.HttpContext);
        }

ExportReport: گزارش ساز استیمول به شما اجاز میدهد در فرمت‌های گوناگونی چون xlsx,docx,pptx,pdf,rtf و ... از گزارش خود خروجی بگیرید. اطلاعات گزارش از طریق شی HttpContext به سمت اکشن متد ارسال شده و توسط ExportReportResult  دریافت می‌شود. 
 public virtual ActionResult ExportReport()
        {
            return StiMvcViewer.ExportReportResult(this.HttpContext);
        }
حال اگر برنامه را اجرا کنید، باید گزارشی به شکل زیر نمایش داده شود و مقادیر در جای خود شکل گرفته باشند. ولی مشکلی  که ممکن است این گزارش داشته باشد این است که برای فارسی، حالت راست به چپ را ندارد.


 البته خوشبختانه این مشکل  در حالت پیش نمایش و چاپ و خروجی‌ها دیده نمی‌شود و فقط مختص نمایش روی فرم Html است. برای حل این مشکل ممکن است از گزینه یا پراپرتی RightToLeft، در بخش Appearance موجود در helper استفاده کنید که البته استفاده از آن مانند تصویر بالا، فقط محدود به container گزارش و نوار ابزار آن می‌شود. برای حل این مشکل کافی است کد css زیر را به صفحه گزارش اضافه کنید تا مشکل حل شود:
.stiMvcViewerReportPanel table{
    direction:ltr !important;
}
مجددا گزارش را ایجادکنید تا گزارش را به طور صحیحی مشاهده کنید:

حال حتما پیش خود میگویید که این روش برای اطلاعات ایستا و تمرینی مناسب است و من چگونه باید پارامترهای ارسالی به اکشن متد Report را به اکشن متد LoadReportSnapshot ارسال کنم. برای این منظور استفاده از SessionState‌ها زیاد توصیه شده‌است:
 public virtual ActionResult Report(int id)
        {
            TempData["id"]=id;
            return View();
        }

         public virtual ActionResult LoadReportSnapshot()
        {
            var driverId = (int)TempData ["id"];
              //.....
        }
  ولی این روش مشکلات زیادی را دارد. اول اینکه اگر کاربر چند گزارش جداگانه را پشت سر هم باز کند، به دلیل اینکه گزارش مدتی طول می‌کشد باز شود، همه گزارش‌ها آخرین گزارش درخواستی خواهند بود و دوم اینکه مقداری از حافظه سرور را هم بی جهت اشغال میکند. ولی برای کار با استیمول به هیچ یک از این کارها نیازی نیست، چون خود استیمول به طور خودکار پارامترهای ارسالی را انتقال می‌دهد. یعنی کد باید به شکل زیر نوشته شود:
public virtual ActionResult Report(int id)
        {
    
            return View();
        }

         public virtual ActionResult LoadReportSnapshot(int id)
        {
             //.....
        }
همین مقدار کد برای ارسال پارمترها کفایت میکند و مابقی کار را به stimul بسپارید.

نکته بسیار مهم: گزارش ساز استیمول متاسفانه شامل تنظیم پیش فرض نامناسبی است که عملیات کش را بر روی گزارش‌ها اعمال می‌کند. به عنوان مثال تصور کنید من صفحه گزارش شخصی به نام «وحید نصیری» را باز میکنم و در تب دیگر گزارش شخص دیگری با نام «علی یگانه مقدم» را باز میکنم. حال اگر کاربر به سراغ تب آقای نصیری برود و بخواهد چاپ یا خروجی درخواست کند، اشتباها با گزارش علی یگانه مقدم روبرو خواهد شد که این اتفاق به دلیل کش شدن رخ میدهد. برای غیر فعال کردن این قابلیت پیش فرض، کد زیر را در Helper اضافه کنید:
Server =
    {
        GlobalReportCache = false
    }
  • #
    ‫۷ سال و ۱۰ ماه قبل، جمعه ۱۴ آبان ۱۳۹۵، ساعت ۰۴:۴۷
    با تشکر بابت مطلب جاری، همچنین بابت تکمیل پست جاری ما بجای استفاده از
    TempData["id"]=id;
    می‌توان از ارسال مقدارآی‌دی  به صورت پارامتر استفاده نمود و همچنین در اینجا فقط به یک موجودیت برای مثال Person اشاره شده است، با این حال می‌توان بجای استفاده صریح
    report.RegBusinessObject("driverReport", driver);
    و
    report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
    از TempData که برای ارسال آی‌دی استفاده کردید، بهره برد، بدین معنی در گزارش‌های متفاوت کافیست از TempData برای ارسال مسیر فایل MRT و آبجکت استفاده نمود و در متد LoadReportSnapshot به مقادیر ارسالی دسترسی و جایگزاری نمود، با این عمل + فعال سازی طراحی گزارش استیمول به صورت آنلاین یک گزارش داینامیک خواهید داشت.
    البته راه‌های دیگری به منظور داینامیک سازی موجود است اما این روش در پروژه‌های معمولی جوابگو خواهد بود.
  • #
    ‫۷ سال و ۱۰ ماه قبل، یکشنبه ۱۶ آبان ۱۳۹۵، ساعت ۱۳:۵۶
    با تشکر از دوستان
    امکان مدیریت فایل‌های گزارش در دیتابیس نیز وجود دارد؟
  • #
    ‫۷ سال و ۹ ماه قبل، سه‌شنبه ۲۳ آذر ۱۳۹۵، ساعت ۱۶:۱۷
    با سلام؛ چطور می‌تونم برای دو تا جدول که رابطه master-details رو دارند از این روش استفاده کنم. در ریپورت از داده‌های هر دو جدول استفاده کنم.
  • #
    ‫۷ سال و ۹ ماه قبل، سه‌شنبه ۲۳ آذر ۱۳۹۵، ساعت ۲۰:۵۳
    سلام
    محیط گزارش شما فارسیه و توی کدهاتون هم یه فایل fa.xml دارید. این فایل و نحوه فارسی کردن محیط گزارش (نه محیط دیزاین) به چه صورته؟
    • #
      ‫۷ سال و ۹ ماه قبل، سه‌شنبه ۲۳ آذر ۱۳۹۵، ساعت ۲۱:۰۹
      به این خط از کد دقت فرمایید
      @Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions()
      {
          Localization = "~/content/reports/fa.xml",
          .
          .
          .
      }

      • #
        ‫۷ سال و ۹ ماه قبل، سه‌شنبه ۲۳ آذر ۱۳۹۵، ساعت ۲۱:۲۷
        تشکر از پاسخ شما
        بنده هم دقیقا توی سوال منظورم همین بود.
        این فایل و ساختارش و اینکه چطور باید به گزارش معرفیش کرد مد نظرم هست.
        • #
          ‫۷ سال و ۹ ماه قبل، سه‌شنبه ۲۳ آذر ۱۳۹۵، ساعت ۲۱:۴۲
          عموماً در پوشه برنامه Stimulsoft Reports، یک پوشه به نام Localization وجود دارد که برای زبان‌های مختلف از جمله فارسی یک فایل xml دارد. با اضافه کردن این فایل -fa.xml- به پروژه و آدرس‌دهی مناسب با توجه به مثال مطرح شده، محیط گزارش شما فارسی می‌شود. همچنین مثال‌هایی در این مورد در پوشه Samples وجود دارد.
    • #
      ‫۷ سال و ۹ ماه قبل، چهارشنبه ۲۴ آذر ۱۳۹۵، ساعت ۱۷:۳۸
      فایلی که در بالا استفاده شده و آقای بالازاده زحمت مشخص کردنش را کشیدند برای خود محیط گزارش هست.
      فایل‌های گزارشی که در استودیو خود استیمول طراحی میشن از فارسی پشتیبانی کرده و دارای خصوصیت Right to left برای true شدن میباشند.
      همچین در صورتی که مشکل در نمایش داخل خود صفحه وب است در بالا کد css آن ذکر شده است.
  • #
    ‫۷ سال و ۸ ماه قبل، شنبه ۱۱ دی ۱۳۹۵، ساعت ۱۳:۵۴
    ممنون بابت مطلب خوبتون ، اگر بخواهیم با استفاده از اطلاعاتی روی فرم مثلا یک کوئری بین دو تاریخ رو اجرا و گزارشگیری کنیم این پارامترها  رو چطور ارسال کنیم؟ به  LoadReportSnapshot
    • #
      ‫۷ سال و ۸ ماه قبل، شنبه ۱۱ دی ۱۳۹۵، ساعت ۱۴:۳۰
      در مطلب بالا اشاره شد که خود استیمول وظیفه هدایت پارامترها را بر عهده میگیرد. شما دقیقا همان امضای پارامتری را که برای متد اول مشخص کردید برای متد دوم هم خواهید داشت
      • #
        ‫۷ سال قبل، دوشنبه ۲۰ شهریور ۱۳۹۶، ساعت ۱۸:۲۹
        با سلام 
        من در خصوص همین مطلب با این امضا‌های یکسان زیر مشکل مقدار Null دارم. در اکشن report  مقدار درست پاس می‌شه ولی توی LoadReportSnapshot مقدار نال دریافت می‌شود.  
                public virtual   ActionResult Report(Guid personId)
                {
                              return View();
                }
        
                public virtual  ActionResult LoadReportSnapshot(Guid personId)
                {
                  var person = _bossService.GetPersonViewModel(personId);
        + tempdata هم کار نکرد. اونم نال میشه در صورتیکه هیچ read یا redirect ای صورت نگرفته.  
        ممنون میشم اگه راهنمایی کنید.
  • #
    ‫۷ سال و ۷ ماه قبل، دوشنبه ۲ اسفند ۱۳۹۵، ساعت ۱۸:۲۹
    من دارم از این ابزار صرفا برای ایجاد خروجی pdf استفاده میکنم و  وقتی تعداد ستونهای جدولم بیشتر از یک صفحه میشه، صفحه تقسیم میشه  (Segmented Pages ) و  با وجودیکه righttoleft   هست ولی عملا ستونها رو از چپ شروع میکنه به چیدن، نتیجه اینکه صفحه دوم رو پر میکنه و  صفحه‌ی اول چند ستون باقیمانده‌ی ابتدای جدول رو نشون میده.  ممنون میشم راهنماییم کنید  
    • #
      ‫۷ سال و ۷ ماه قبل، سه‌شنبه ۳ اسفند ۱۳۹۵، ساعت ۱۷:۰۹
      در صورت امکان فایل گزارش (mrt) را برای بررسی قرار دهید.
  • #
    ‫۶ سال و ۹ ماه قبل، شنبه ۱۱ آذر ۱۳۹۶، ساعت ۰۳:۰۷
    سلام؛ من از این روش برای پیاده سازی خودم و تهیه گزارش استفاده کردم، اما وقتی View من فراخونی میشه هیچ یکی از متدهای GetReportSnapshot و یا ViewerEvent  و یا PrintReport فراخوانی نمی‌شن و در عوض خود متد فراخواننده View گزارش فراخوانی میشه. به عبارت بهتر وقتی من متد گزارش رو به آدرس
     http://localhost:14425/tableproduct/printtable?reporttype=21
    فراخوانی میکنم این آدرس یک بار فراخوانی شده و سپس View فراخوانی می‌شود و View درخواستی به شکل زیر را به سرور می‌دهد :
    /tableproduct/PrintTable?reporttype=21&mvcviewer_resource=scripts&mvcviewer_id=MVCViewer1&mvcviewer_theme=Office2013&mvcviewer_loc=
    fi9Db250ZW50L1N0aW11bHNvZnQvTG9jYWxpemF0aW9uL2ZhLnhtbA%3d%3d&mvcviewer_version=2015.2 
    به نظر شما دلیل این مشکل چی میتونه باشه؟ نتیجه بررسی‌های خودم نشون میده احتمالا مشکل از CustomRoute من هستش. پروژه ای که من دارم گزارش رو توی اون ایجاد میکنم از ساختار Routing پروژه Iris  استفاده میکنه.
    • #
      ‫۶ سال و ۹ ماه قبل، شنبه ۱۱ آذر ۱۳۹۶، ساعت ۱۵:۳۶
      مطلب «نحوه صحیح تولید Url در ASP.NET MVC» را پیگیری کنید (چون هر کدام از نام‌های اکشن متدهای درج شده‌ی در View در حقیقت یک URL هستند و نه صرفا یک نام خالی و اگر نیاز به آدرس صحیح آن‌ها را دارید باید از سیستم مسیریابی، آن‌ها را توسط Url.Action کوئری بگیرید).  
      • #
        ‫۶ سال و ۹ ماه قبل، یکشنبه ۱۲ آذر ۱۳۹۶، ساعت ۰۱:۰۵
        با سلام؛ از روش مورد اشاره مقاله استفاده کردم. کد فایل report.chtml به شکل زیر تغییر یافت :
         @Html.Stimulsoft().StiMvcViewer("MVCViewer1", new StiMvcViewerOptions()
                   {
                       Actions = new StiMvcViewerOptions.ActionOptions()
                       {
                           GetReportSnapshot =
                           Url.Action(
                               MVC.TableProduct.Report.ActionNames.CustomReportSnapshot,
                           MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name }, "http"),
                           ViewerEvent =
                           Url.Action(
                               MVC.TableProduct.Report.ActionNames.CustomViewerEvent,
                               MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name }, "http"),
                           PrintReport =
                           Url.Action(
                               MVC.TableProduct.Report.ActionNames.CustomPrintReport,
                               MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name },"http"),
                       },
                       Server = new StiMvcViewerOptions.ServerOptions()
                       {
                           PassFormValues = true,
                           GlobalReportCache = false,
                           Controller = MVC.TableProduct.Report.Name
        
                       },
                       Exports = new StiMvcViewerOptions.ExportOptions()
                       {
                           ShowExportToPdf = true,
                           ShowExportToCsv = true
                       },
                       Toolbar = new StiMvcViewerOptions.ToolbarOptions()
                       {
                           ShowDesignButton = false,
                           ShowEditorButton = false,
                           ShowParametersButton = false,
                           ShowViewModeButton = true
                       },
        
                       Localization = "~/Content/Stimulsoft/Localization/fa.xml",
                       Width = Unit.Percentage(100),
                       Theme = StiTheme.Office2013,
        
                   })
        در این کد مسیر Action‌ها به درستی ایجاد شده است. برای مثال برای متد getReportSnapshot  آدرس زیر تولید شده است :
        http://localhost:14425/tableproduct/customreportsnapshot 
        این آدرس کاملا صحیح بوده و با PostMan قابل فراخوانی است. اما همچنان مشکل فوق پابرجا بوده و گزارش نشان داده نشده و هیچ یک از متد‌های پرینت فراخوانی نمی‌شوند.
        • #
          ‫۶ سال و ۹ ماه قبل، یکشنبه ۱۲ آذر ۱۳۹۶، ساعت ۰۱:۳۲
          - کار کردن با T4MVC به سادگی ذیل است (همیشه از پارامتر result آن استفاده کنید):
          GetReportSnapshot = Url.Action(result: MVC.Report.CustomReportSnapshot()),
          //...
          - این مطلب را هم برای دیباگ مدنظر داشته باشید: «نحوه استفاده از افزونه Firebug برای دیباگ برنامه‌های ASP.NET مبتنی بر jQuery » 
          • #
            ‫۵ سال قبل، شنبه ۹ شهریور ۱۳۹۸، ساعت ۲۲:۳۷
            برای بنده هم این مشکل پیش آمده. به شکل زیر نوشتم. این کار رو هم کردم. باز هم مشکل وجود داره و به GetReport ارجاع پیدا نمیکنه. 
            GetReport = Url.Action("GetPuFish", "Report", null, "http")
              • #
                ‫۵ سال قبل، یکشنبه ۱۰ شهریور ۱۳۹۸، ساعت ۱۳:۱۳
                خیلی وقته استفاده میکنم و قبلا مشکلی نداشتم و دقیقا طبق مثال نوشتم. قبلا با نسخه ۲۰۱۸/۳/۲ کار میکردم. الان ۲۰۱۹ رو نصب کردم. نمیدونم به نسخه نرم افزار مربوطه یا نه؟
              • #
                ‫۵ سال قبل، یکشنبه ۱۰ شهریور ۱۳۹۸، ساعت ۱۵:۰۱
                حل شد . پاک کردن و دوباره نصب کردم و از dll‌های خود پوشه اصلی stimulsoft استفاده کردم .
  • #
    ‫۶ سال و ۹ ماه قبل، جمعه ۱۷ آذر ۱۳۹۶، ساعت ۲۲:۱۱
    سلام؛ من گزارشی طراحی کردم که از فونت b nazanin استفاده کرده. گزارش در زمان debug به خوبی با فونت b nazanin نشان داده میشه ولی وقتی روی وب publish میشه فونت اون به microsoft san serif تغییر کرده و به هم میریزه. میشه راهنمایی بفرمائید ؟
      • #
        ‫۶ سال و ۹ ماه قبل، جمعه ۱۷ آذر ۱۳۹۶، ساعت ۲۳:۳۸
        من روش توضیح داده شده رو تست کردم. به این صورت که کد زیر رو به فایل report.chtml اضافه کردم :
        @section styles{
            <style>
                @@font-face {
                    font-family: 'Shiraz';
                    src: url('../fonts/BShiraz.eot');
                    src: url('../fonts/BShiraz.eot?#iefix') format('embedded-opentype'), url('../fonts/BShiraz.woff') format('woff'), url('../fonts/BShiraz.ttf') format('truetype');
                    font-weight: normal;
                }
            </style>
        }
        حالا این فونت باید به کدام تگ در report.chtml اضافه شود ؟
        • #
          ‫۶ سال و ۹ ماه قبل، شنبه ۱۸ آذر ۱۳۹۶، ساعت ۰۵:۳۳
          Custom Fonts in Azure
          StiFontCollection.AddFontFile("d:\\before_the_rain.ttf");

          @font-face {
              font-family: myFirstFont;
              src: url(sansation_light.woff);
          }
          • #
            ‫۴ سال و ۱۰ ماه قبل، چهارشنبه ۸ آبان ۱۳۹۸، ساعت ۱۲:۱۳
            زمانیکه خروجی pdf رو ذخیره میکنم و بصورت مجزا باز میکنم، بعضی از کاراکتر‌ها به شکل مربع نمایش داده می‌شود. اما خارج از فرمت pdf همه چی به درستی مشاهده می‌شود. از این دستور استفاده کردم ولی فرقی نکرد:
            Stimulsoft.Base.StiFontCollection.AddFontFile
            • #
              ‫۴ سال و ۱۰ ماه قبل، چهارشنبه ۸ آبان ۱۳۹۸، ساعت ۱۳:۰۷
              اگر تولید کننده‌ی PDF آن در حد و اندازه‌های iTextSharp باشد (که نیست) و اگر قابلیت Font Selector آن‌را اضافه کرده باشد (که اینطور نیست)، می‌تواند از چندین فونت استفاده کند: «iTextSharp و استفاده از قلم‌های محدود فارسی». در غیر اینصورت تنها راه حل موجود برای این موارد استفاده از یک قلم فارسی کامل است.
    • #
      ‫۶ سال و ۹ ماه قبل، شنبه ۱۸ آذر ۱۳۹۶، ساعت ۰۰:۱۲
      سلام
      آگر در سرور فونت نصب نشده باشد این مشکل به وجود می‌آید، احتمالا بعد از نصب فونت ،لازم هست که یکبار سرور ریست بشه.
  • #
    ‫۶ سال و ۶ ماه قبل، دوشنبه ۷ اسفند ۱۳۹۶، ساعت ۱۷:۵۵
    در ورژن 2017 از متد getreport به جای getsnapshotreport استفاده کرده. آیا امکان توضیح تفاوت این دو متد وجود دارد؟
  • #
    ‫۶ سال و ۴ ماه قبل، سه‌شنبه ۴ اردیبهشت ۱۳۹۷، ساعت ۱۶:۲۹
     موقع دیباگ با خود ویژوال استودیو پرینت مستقیم به خوبی جوابگو هست ولی
    بعد از پابلیش کردن پروژه و استقرار در IIS هنگام ارسال مستقیم گزارش به پرینتر (بدون پیش نمایش)  خطای زیر را صادر میکند 
    Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid
    operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application
    گویا در وب امکان ارسال مستقیم به پرینتر وجود ندارد آیا راه حلی وجود دارد؟
    با تشکر  
    • #
      ‫۶ سال و ۴ ماه قبل، پنجشنبه ۶ اردیبهشت ۱۳۹۷، ساعت ۰۲:۲۷
      کد زیر را به کدهایتان اضافه کنید و سعی کنید لاگ مورد نظر را از استیمول دریافت کنید
      Stimulsoft.Report.StiLogService.LogEnabled = true;
      StiLogService service = StiConfig.Services.GetService(typeof(StiLogService)) as StiLogService;
      service.LogPath = "Report.log"; // مسیر کامل و Mappath شده
  • #
    ‫۶ سال و ۴ ماه قبل، دوشنبه ۳۱ اردیبهشت ۱۳۹۷، ساعت ۰۴:۱۵
    در تکمیل مطلب ،
     جهت ایجادسریعتر و دقیقتر ستون‌های اطلاعاتی همانطور که در تصویر هم مشخص شده میتوان روی گزینه Get Column From Assembly کلیک و از اسمبلیِ Model‌ها استفاده کرد . بنظر میرسد با این کار به هماهنگی بیشتری با معماری MVC هم  میرسیم.
  • #
    ‫۵ سال و ۸ ماه قبل، سه‌شنبه ۲۵ دی ۱۳۹۷، ساعت ۱۵:۲۸
    سلام؛ من طبق آموزش شما پیش می‌رم ولی همیشه خطای زیر را میگیرم
    Could not load file or assembly 'Stimulsoft.Base' or one of its dependencies. Strong name signature could not be verified.  The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key. (Exception from HRESULT: 0x80131045)
    آیا مشکل از .dll هاست؟
    • #
      ‫۵ سال و ۸ ماه قبل، سه‌شنبه ۲۵ دی ۱۳۹۷، ساعت ۱۶:۰۱
      سایت جاری در این زمینه فعالیت نمی‌کند. برای این نوع موارد مراجعه کنید به اینجا
  • #
    ‫۵ سال و ۶ ماه قبل، شنبه ۴ اسفند ۱۳۹۷، ساعت ۱۴:۰۵
    با عرض ادب. 
    در ورژن جدید ظاهرا متد GetReportSnapshotResult رو برداشتند .چون این خطارومیده : 
    Warning CS0618 'StiMvcViewer.GetReportSnapshotResult(HttpContextBase, StiReport)' is obsolete: 'This method is obsolete. It will be removed in next versions. Please use the GetReportResult(report) method instead.
    در ویو هم برای GetReportSnapshot این خطا رو میده.
    آیا همان پیشنهادی که بهم داده رو استفاده کنم. یعنی از GetReportResult استفاده کنم؟
    • #
      ‫۵ سال و ۶ ماه قبل، یکشنبه ۵ اسفند ۱۳۹۷، ساعت ۱۷:۴۷
      تغییرات جدید را در این صفحه مشاهده کنید.
  • #
    ‫۵ سال قبل، چهارشنبه ۳۰ مرداد ۱۳۹۸، ساعت ۱۲:۴۵
    سلام
    زمانی که پرینت میکنم توی نمایش اعداد فارسی نشون میده ولی وقتی چاپ میکنم انگلیسی میشه بنظرتون مشکل چیه؟
    • #
      ‫۵ سال قبل، چهارشنبه ۳۰ مرداد ۱۳۹۸، ساعت ۱۳:۱۵
      یکسری از فونت‌های فارسی دستکاری شدن و بجای اعداد واقعی که انگلیسی هستند، گلیف‌های نمایشی فارسی رو قرار دادن. این نوع فونت‌ها هم در هنگام نمایش و هم در هنگام پرینت، به یک صورت رفتار می‌کنند و وابسته به تنظیمات سیستم عامل شما نیستند.
      • #
        ‫۵ سال قبل، چهارشنبه ۳۰ مرداد ۱۳۹۸، ساعت ۱۳:۵۶
        خب از چه فونتی استفاده کنم؟ با همین فونت توی برنامه Word مشکل ندارم.
        • #
          ‫۵ سال قبل، چهارشنبه ۳۰ مرداد ۱۳۹۸، ساعت ۱۴:۰۴
          بسته samim پوشه مخصوص farsi-digits هم داره
      • #
        ‫۵ سال قبل، چهارشنبه ۳۰ مرداد ۱۳۹۸، ساعت ۱۶:۰۷
        ممنون با این فونت هم نشد ولی bnazanain جواب داد
  • #
    ‫۴ سال و ۸ ماه قبل، دوشنبه ۲ دی ۱۳۹۸، ساعت ۱۵:۲۰
    سلام؛ بنده یک لیست تو در تو دارم؛ مثلا چندتا گروه دارم هر گروه چندتا آیتم داره:
    [
       {
          "day" : "۱۳۹۸/۱۰/۲۵",
          "plan" : "موردی",
          "rId" : 1,
          "records" : [
             {
                "help" : "بسته غذایی",
                "rId" : 1
             },
             {
                "help" : "کمک مالی",
                "rId" : 1
             }
          ]
       },
       {
          "day" : "۱۳۹۸/۱۰/۱۶",
          "plan" : "مادرانه",
          "rId" : 1002,
          "records" : [
             {
                "help" : "بسته غذایی",
                "rId" : 1002
             },
             {
                "help" : "تدریس",
                "rId" : 1002
             }
          ]
       }
    ]
    ممنون میشم راهنماییم کنید چطور پیاده سازیش کنم.
    • #
      ‫۴ سال و ۸ ماه قبل، دوشنبه ۲ دی ۱۳۹۸، ساعت ۱۶:۵۲
      در سمت سرور کلاس‌هایی به صورت زیر می‌توانید داشته باشید:
      public class PlanModel
      {
          public int RId { get; set; }
          public string Day { get; set; }
          public string Plan { get; set; }
          public List<RecordModel> Records { get; set; }
      }
      
      public class RecordModel
      {
          public int RId { get; set; }
          public string Help { get; set; }
      }
      که لیستی از PlanModel پس از فراهم کردن اطلاعاتش،  به گزارش ارسال می‌کنید.
      در فایل mrt گزارش خود نیز در قسمت Business Objects دو Business Object تولید می‌کنید، که مدل دوم (از نوع RecordModel) به عنوان فرزند مدل اول (از نوع PlanModel) است.

      برای نمایش اطلاعات این دو مدل هم، به دو Data band احتیاج دارید.

       نکته‌ای که در اینجا مهم است باید پراپرتی Master Component، بند دوم برابر بند اول مقداردهی شود.
      نمونه فایل: MultiBusinessObject.mrt 
      • #
        ‫۳ سال و ۹ ماه قبل، سه‌شنبه ۴ آذر ۱۳۹۹، ساعت ۰۵:۳۳
        درود
        لطفا بفرمائید برای گزارشهای سه سطحی چگونه بایدعمل کرد
        و fill کردن دیتای آنها در .net core چطور است
        • #
          ‫۳ سال و ۹ ماه قبل، سه‌شنبه ۴ آذر ۱۳۹۹، ساعت ۱۶:۵۹
          مانند مثال بالا می‌توانید به سطوح جزییات گزارش خود بیافزایید. به طور مثال مدل‌های زیر را در نظر بگیرید:
            public class CustomerServiceReport
            {
                  public string ReportTitle { get; set; }
                  public string ReportDate { get; set; }
                  //...
          
                  public List<CustomerRow> Customers { get; set; } = new List<CustomerRow>(); 
            }
          
           public class CustomerRow
           {
                  public int CustomerId { get; set; }
                  public string CustomerName { get; set; }
                  public string Phone { get; set; }
                  //...
          
                  public List<ServiceRow> Services { get; set; } = new List<ServiceRow>();  
          } public class ServiceRow { public int ServiceId { get; set; } public string ServiceName { get; set; } public int Count { get; set; } public long Price { get; set; } }
          که در فایل mrt مربوط به گزارش به صورت زیر پیاده‌سازی می‌شود

          در برنامه هم به صورت زیر دیتای مورد نیاز گزارش - به صورت نمونه - ایجاد می‌شود و در انتها با استفاده از RegBusinessObject و SynchronizeBusinessObjects به گزارش ثبت و ارسال می‌گردد.
          var data = new CustomerServiceReport
          {
              ReportDate = "1399/09/04",
              ReportTitle = "گزارش سرویس‌های مشتریان"
          };
          
          for (int i = 0; i < 5; i++)
          {
              var customer = new CustomerRow
              {
                  CustomerId = i + 1,
                  CustomerName = $"مشتری شماره {i + 1}",
                  Phone = "001122"
              };
          
              for (int j = 0; j < 3; j++)
              {
                  var service = new ServiceRow
                  {
                      ServiceId = j + 1,
                      ServiceName = $"سرویس شماره {j + 1}",
                      Count = (j + 1) * 10,
                      Price = (j + 1) * 10000
                  };
          
                  customer.Services.Add(service); //اضافه کردن سرویس به هر مشتری
              }
          
              data.Customers.Add(customer); // اضافه کردن مشتری به گزارش
          }
          
          var report = new StiReport();
          report.RegBusinessObject("CustomerServiceReport", data);
          report.Dictionary.SynchronizeBusinessObjects();

          • #
            ‫۳ سال و ۹ ماه قبل، چهارشنبه ۵ آذر ۱۳۹۹، ساعت ۲۰:۵۸
            سپاس؛ پاسخ بسیار مفیدی دادید. بنده در net core mvc. استفاده میکنم. مشکلی که پیش آمد  وقتی خروجی pdf از گزارش میگیرم در متد:
            public IActionResult ViewerEvent()
            {
               return StiNetCoreViewer.ViewerEventResult(this);
            }
            خطای زیر ظاهر میشود:
            System.ArgumentException: 'Must specify valid information for parsing in the string. '
            در صورتی که گزارش به درستی نمایش داده میشود وسایر خروجی‌ها مشکلی ندارد.
             نکته دیگر اینکه  از کد خط آخری جنابعالی استفاده نکردم
            report.Dictionary.SynchronizeBusinessObjects();
            
            آیا مشکلی پیش می‌آید؟
            • #
              ‫۳ سال و ۹ ماه قبل، پنجشنبه ۶ آذر ۱۳۹۹، ساعت ۱۲:۴۹
              در مورد خطا، اگر فایل گزارش و دیتای آن موجود باشد شاید بتوان بررسی کرد.
              در مورد متد SynchronizeBusinessObjects  و یا  Synchronize - برای RegData - هم برای ایجاد ساختار دیتای ارسالی به گزارش در قسمت Dictionary استفاده می‌شود و اجباری به استفاده از آن نیست. می‌توان بر اساس پارامتر maxLevel  تعداد لایه‌های نمایش را مقداردهی کرد.
              در مثال بالا به صورت زیر نتایج خروجی آن را با هم مقایسه کنید:
              report.RegBusinessObject("CustomerServiceReport", data);
              
              report.Save(StiNetCoreHelper.MapPath(this, "Reports/CustomerServiceReportNoSync.mrt"));
              
              report.Dictionary.SynchronizeBusinessObjects();
              report.Save(StiNetCoreHelper.MapPath(this, "Reports/CustomerServiceReportSync.mrt"));
              
              report.Dictionary.SynchronizeBusinessObjects(0);
              report.Save(StiNetCoreHelper.MapPath(this, "Reports/CustomerServiceReportSync0.mrt"));
              
              report.Dictionary.SynchronizeBusinessObjects(1);
              report.Save(StiNetCoreHelper.MapPath(this, "Reports/CustomerServiceReportSync1.mrt"));
              
              report.Dictionary.SynchronizeBusinessObjects(2);
              report.Save(StiNetCoreHelper.MapPath(this, "Reports/CustomerServiceReportSync2.mrt"));

              NoSync

              Sync

               Sync0

              Sync1

              Sync2


  • #
    ‫۳ سال و ۱ ماه قبل، دوشنبه ۲۱ تیر ۱۴۰۰، ساعت ۱۹:۰۸
    با توجه به عرضه نسخه net core.، این گزارشگر هم تغییراتی در نسخه‌های اخیر خود داده و هم اینکه پیشرفت‌های زیادی نیز کرده است.
    بعد از نصب نسخه مورد نظر (برای نسخه 3.1 نیاز به نصب استیمول 2020 است) طبق این لینک مشکل Trial بودن (برای ما)  را حل کنید.
    در مورد این لینک چند نکته قابل ذکر است:
    1- از شما میخواهد که dll‌های جایگزین بعد از build، با dll‌ها اصلی جابجا شوند که انجام این مورد در Visual Studio به خاطر داشتن UI برای اینکار به راحتی انجام می‌شد ولی در Visual Studio Code و Rider، چنین موردی باید به صورت دستی صورت بگیرد؛ به همین علت در فایل csproj پروژه اصلی، کدهای زیر را اضافه کنید:
      <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="xcopy /y /d $(ProjectDir)Packages\*.* $(OutDir)" />
      </Target>
    2- همچنین در نهایت باید فایل لایسنس نیز در پروژه قرار گرفته و در Startup به استیمول معرفی گرد. به همین جهت کلاس زیر را اضافه کنید:
     public static class StimulSoftLicense
        {
            public static void LoadLicense(IWebHostEnvironment environment)
            {
                var contentRoot = environment.ContentRootPath;
                var licenseFile = System.IO.Path.Combine(contentRoot,"Reports", "license.key");
                Stimulsoft.Base.StiLicense.LoadFromFile(licenseFile);
            }
        }
    که در خط دوم مسیر فایل لایسنس معرفی شده است که برای پروژه شما باید اصلاح شود و در startup.cs به صورت زیر استفاده میشود:
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
               StimulSoftLicense.LoadLicense(env);
    }
    برای نمایش گزارش همه چیز کماکان مثل سابق است فقط یک سری جزئیات تغییر نموده است:
            public IActionResult RequestReport(int id)
            {
                return View();
            }
    
            public IActionResult LoadReportData(int id)
            {
                StiReport report = new StiReport();
                report.Load(StiNetCoreHelper.MapPath(this, "Reports/Requests/RequestInfo.mrt"));
                var landDetailsReport = GetOwnerReportData(id);
                report.RegBusinessObject("Land", landDetailsReport);
    
                return StiNetCoreViewer.GetReportResult(this, report);
            }
             public IActionResult ViewerEvent()
            {
                return StiNetCoreViewer.ViewerEventResult(this);
            }
    همچنین در ویو RequestReport.cshtml کد به شکل زیر تغییر میکند:
    <div style="direction: ltr">
        
    @Html.StiNetCoreViewer(new StiNetCoreViewerOptions()
    {
        Theme = StiViewerTheme.Office2007Silver,
        
        Appearance =
        {
            RightToLeft = true,
            //ShowTooltips = false,
            ShowTooltipsHelp = false,
            
        },
    Localization = "~/Reports/fa.xml",
        Actions =
        {
            GetReport = "LoadReportData",
            ViewerEvent = "ViewerEvent",
            
        },
        Toolbar =
        {
          ShowAboutButton  = false,
            ShowOpenButton = false,
            ShowSaveButton = true,
            ShowFindButton = false,
            ShowEditorButton = false,
            ShowDesignButton = false,
            ShowBookmarksButton = false,
            ShowResourcesButton = false,
            ShowParametersButton = false,
            ShowPinToolbarButton = false
    
        },
        Exports =
        {
            DefaultSettings =
            {
                ExportToPdf =
                {
                    CreatorString = "SANA"
                }
            },
            ShowExportDialog = false,
            ShowExportToDocument = false,
            ShowExportToExcel = false,
            ShowExportToExcel2007 = false,
            ShowExportToHtml = false,
            ShowExportToHtml5 = false,
            ShowExportToImageBmp = false,
            ShowExportToImageJpeg = false,
            ShowExportToImagePcx = false,
            ShowExportToImagePng = false,
            ShowExportToImageMetafile = false,
            ShowExportToImageTiff = false,
            ShowExportToOpenDocumentCalc = false,
            ShowExportToMht = false,
            ShowExportToOpenDocumentWriter = false,
            ShowExportToXps = false,
            ShowExportToSylk = false,
            ShowExportToRtf = false,
            ShowExportToExcelXml = false,
            ShowExportToText = false,
            ShowExportToWord2007 = false,
            ShowExportToImageGif = false,
            ShowExportToCsv = false,
            ShowExportToDbf = false,
            
            ShowExportToDif = false,
            ShowExportToImageSvg = false,
            ShowExportToImageSvgz = false,
            ShowExportToPowerPoint = false,
            ShowExportToXml = false,
            ShowExportToJson = false
        }
    })
    </div>
    با توجه به نیاز کد بالا را تغییر دهید. تقریبا تا حدی خصوصیت‌ها تغییر کرده‌اند ولی نه خیلی.
    یک نکته مهم در مورد div که این helper را محصور کرده وجود دارد و آن این است که حالت RTL  قالب شما روی Helper استیمول تاثیر میگذارد ( به خصوص روی خود گزارش) برای همین از تنظیمات داخل خود Helper برای اینکار استفاده میکنیم؛ ولی اگر قالب RTL باشد و استیمول هم روی RTL تنظیم شود در نوار ابزار، ترتیب ابزار‌ها معکوس میگردد. به همین دلیل حالت پیش فرض، یعنی LTR میباشد و با تظیم Helper به این مهم دست پیدا می‌کنیم.
    کدهای زیر را نیز به فایل css صفحه اضافه کنید تا در گزارش ساز استیمول اعمال گردد:
    .stiJsViewerClearAllStyles
    {
        font-family: "IRANSans" !important;
    }
    
    //مخصوص دیالوگ تنظیمات خروجی در صورت فعال بودن
    .stiJsViewerGroupPanelContainer{
        direction: rtl !important;
    }
    .stiJsViewerFormButtonDefault{
        direction: rtl !important;
    }
    .stiJsViewerFormButtonOver{
        direction: rtl !important;
    }
    .stiJsViewerFormButtonDefault>table>tbody>tr>td{
        text-align: right !important;
    }
    .stiJsViewerFormButtonOver>table>tbody>tr>td{
        text-align: right !important;
    }
    .stiJsViewerFormHeader{
        direction: rtl;
    }
    .stiJsViewerFormHeader>table>tbody>tr>td{
        text-align: right !important;
    }
    .stiJsViewerCheckBox{
        direction:rtl !important;
    }
    .stiJsViewerDropdownPanel{
        direction:rtl !important;
    }
    .stiJsViewerFormContainer td.stiJsViewerClearAllStyles{
        direction:rtl !important;
    }
     .stiMvcViewerReportPanel table{
         direction:ltr !important;
     }
    • #
      ‫۲ سال و ۲ ماه قبل، دوشنبه ۲۳ خرداد ۱۴۰۱، ساعت ۱۲:۵۳
      سلام و احترام
      کاش یه گزارش رو برای دات نت کور از اول مینوشتید.