{"id":43219,"date":"2026-07-10T09:15:38","date_gmt":"2026-07-10T06:15:38","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/"},"modified":"2026-07-10T09:16:44","modified_gmt":"2026-07-10T06:16:44","slug":"rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/","title":{"rendered":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma"},"content":{"rendered":"<h2>Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma<\/h2>\n<p>E\u011fitim kurumlar\u0131nda, \u00f6\u011frenci raporlar\u0131 olu\u015fturmak genellikle zaman al\u0131c\u0131 ve hataya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Not d\u00f6k\u00fcmleri, ba\u015far\u0131 belgeleri veya d\u00f6nem sonu de\u011ferlendirmeleri gibi raporlar, her \u00f6\u011frenci i\u00e7in ki\u015fiselle\u015ftirilmi\u015f veriler i\u00e7erir ve genellikle PDF format\u0131nda sunulmalar\u0131 gerekir. Peki, bu karma\u015f\u0131k ve tekrarlayan g\u00f6revi Rust gibi performans odakl\u0131 bir dil ile nas\u0131l otomatikle\u015ftiririz? HTML \u015fablonlar\u0131n\u0131n esnekli\u011fini kullanarak dinamik raporlar olu\u015fturup bunlar\u0131 g\u00fcvenilir bir \u015fekilde PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrmek, hem zamandan tasarruf etmenizi hem de insan kaynakl\u0131 hatalar\u0131 minimuma indirmenizi sa\u011flayabilir. Bu makalede, Rust&#8217;\u0131n g\u00fcc\u00fcn\u00fc, modern web teknolojilerinin esnekli\u011fiyle birle\u015ftirerek \u00f6\u011frenci raporu \u00fcretimini ba\u015ftan sona nas\u0131l otomatikle\u015ftirebilece\u011finizi ad\u0131m ad\u0131m ke\u015ffedece\u011fiz. Gelin, bu s\u00fcreci birlikte inceleyelim ve manuel raporlama kabusuna veda edelim.<\/p>\n<h3>Neden Rust ve HTML \u015eablonlar\u0131 ile Rapor Olu\u015fturmal\u0131y\u0131z?<\/h3>\n<p>Rapor olu\u015fturma s\u00fcre\u00e7lerinde kar\u015f\u0131la\u015f\u0131lan temel zorluklardan biri, verilerin do\u011fru ve tutarl\u0131 bir \u015fekilde sunulmas\u0131d\u0131r. \u00d6zellikle b\u00fcy\u00fck \u00f6\u011frenci kitlelerine sahip kurumlarda, her bir raporun manuel olarak haz\u0131rlanmas\u0131, hem b\u00fcy\u00fck bir i\u015f y\u00fck\u00fc yarat\u0131r hem de hata yapma olas\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r. Bu noktada, otomatikle\u015ftirilmi\u015f bir sistem kurmak ka\u00e7\u0131n\u0131lmaz hale gelir. Peki, neden bu otomasyon i\u00e7in Rust&#8217;\u0131 ve HTML \u015fablonlar\u0131n\u0131 tercih etmeliyiz?<\/p>\n<p>Rust, modern sistem programlama dillerinden biri olarak, \u00f6zellikle performans, g\u00fcvenlik ve e\u015fzamanl\u0131l\u0131k (concurrency) konular\u0131nda \u00f6ne \u00e7\u0131kar. Bellek g\u00fcvenli\u011fi garantileri sayesinde, raporlama sisteminizde olu\u015fabilecek yayg\u0131n hatalar\u0131n (\u00f6rne\u011fin, null pointer dereferencing veya veri yar\u0131\u015flar\u0131) \u00f6n\u00fcne ge\u00e7ilir. Bu, \u00f6zellikle hassas \u00f6\u011frenci verileriyle \u00e7al\u0131\u015f\u0131rken kritik bir avantajd\u0131r. Y\u00fcksek performans beklentisi olan uygulamalar i\u00e7in ideal bir se\u00e7imdir; binlerce \u00f6\u011frenci raporunu saniyeler i\u00e7inde i\u015fleyebilir ve PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrebilir. Bu h\u0131z, yo\u011fun d\u00f6nemlerde raporlama s\u00fcre\u00e7lerinin aksamadan ilerlemesini sa\u011flar. Ayr\u0131ca, Rust&#8217;\u0131n g\u00fc\u00e7l\u00fc t\u00fcr sistemi (type system), geli\u015ftirme a\u015famas\u0131nda bir\u00e7ok hatay\u0131 yakalaman\u0131za yard\u0131mc\u0131 olarak daha g\u00fcvenilir ve bak\u0131m\u0131 kolay kod yazman\u0131z\u0131 te\u015fvik eder. Bu sayede, rapor \u015fablonlar\u0131n\u0131zdaki veri entegrasyonu da daha sa\u011flam temellere oturur.<\/p>\n<p>HTML \u015fablonlar\u0131 ise, raporlar\u0131n g\u00f6rsel tasar\u0131m\u0131n\u0131 ve esnekli\u011fini sa\u011flar. HTML, web taray\u0131c\u0131lar\u0131n\u0131n do\u011fal dili oldu\u011fu i\u00e7in, rapor tasar\u0131mlar\u0131n\u0131z\u0131 CSS ile zenginle\u015ftirebilir, JavaScript ile dinamik \u00f6\u011feler ekleyebilir (ger\u00e7i PDF&#8217;e d\u00f6n\u00fc\u015f\u00fcmde JS genellikle \u00e7al\u0131\u015fmaz) ve mevcut web tasar\u0131m becerilerinizden faydalanabilirsiniz. Tera veya Handlebars gibi Rust ile uyumlu \u015fablon motorlar\u0131, verilerinizi kolayca HTML iskeletine entegre etmenize olanak tan\u0131r. Bu sayede, raporlar\u0131n\u0131z\u0131n format\u0131 ve i\u00e7eri\u011fi birbirinden ayr\u0131l\u0131r; tasar\u0131mc\u0131lar HTML\/CSS \u00fczerinde \u00e7al\u0131\u015f\u0131rken, geli\u015ftiriciler veri i\u015fleme ve entegrasyonuna odaklanabilir. Bu ayr\u0131m, i\u015f ak\u0131\u015f\u0131n\u0131 h\u0131zland\u0131r\u0131r ve rapor tasar\u0131mlar\u0131nda yap\u0131lan de\u011fi\u015fikliklerin kod taraf\u0131nda minimum m\u00fcdahale gerektirmesini sa\u011flar. \u00d6rne\u011fin, bir \u00fcniversite y\u00f6netiminin d\u00f6nemlik rapor format\u0131nda de\u011fi\u015fiklik yapmas\u0131 gerekti\u011finde, sadece HTML \u015fablonunu g\u00fcncellemek yeterli olacakt\u0131r. Bu esneklik, uzun vadede sistemin s\u00fcrd\u00fcr\u00fclebilirli\u011fini ve adaptasyon yetene\u011fini art\u0131r\u0131r. \u00d6zetle, Rust&#8217;\u0131n g\u00fcvenilirli\u011fi ve h\u0131z\u0131 ile HTML&#8217;in g\u00f6rsel esnekli\u011fini birle\u015ftirmek, \u00f6\u011frenci raporlama s\u00fcre\u00e7lerini modern, verimli ve hatas\u0131z hale getirmenin anahtar\u0131d\u0131r.<\/p>\n<h3>Rust Projemizi Ba\u015flatma ve Temel Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Y\u00f6netme<\/h3>\n<p>Rust ile dinamik \u00f6\u011frenci raporlar\u0131 olu\u015fturma ser\u00fcvenimize ba\u015flamak i\u00e7in \u00f6ncelikle yeni bir Rust projesi olu\u015fturmam\u0131z ve gerekli k\u00fct\u00fcphaneleri (crate) projemize dahil etmemiz gerekiyor. Bu ad\u0131m, t\u00fcm sistemin temelini olu\u015fturacak ve ilerleyen ad\u0131mlarda kullanaca\u011f\u0131m\u0131z ara\u00e7lar\u0131 bize sa\u011flayacakt\u0131r. Rust&#8217;\u0131n paket y\u00f6neticisi Cargo sayesinde bu s\u00fcre\u00e7 olduk\u00e7a basittir.<\/p>\n<p>\u0130lk olarak, komut sat\u0131r\u0131n\u0131z\u0131 a\u00e7\u0131n ve yeni bir Cargo projesi olu\u015fturun:<\/p>\n<div class=\"code-container\">\n<pre><code>cargo new ogrenci_raporlari\ncd ogrenci_raporlari<\/code><\/pre>\n<\/div>\n<p>Bu komutlar, <code>ogrenci_raporlari<\/code> ad\u0131nda yeni bir dizin ve Rust projesi olu\u015fturacakt\u0131r. \u015eimdi, projemizin kalbi olacak ba\u011f\u0131ml\u0131l\u0131klar\u0131 <code>Cargo.toml<\/code> dosyam\u0131za ekleyelim. Bu ba\u011f\u0131ml\u0131l\u0131klar, HTML \u015fablonlar\u0131n\u0131 i\u015flemek, verileri yap\u0131land\u0131rmak ve PDF d\u00f6n\u00fc\u015f\u00fcm\u00fcn\u00fc sa\u011flamak i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<div class=\"code-container\">\n<pre><code># Cargo.toml\n\n[dependencies]\ntera = \"1.19\" # HTML \u015fablon motoru\nserde = { version = \"1.0\", features = [\"derive\"] } # Veri serile\u015ftirme\/deserile\u015ftirme\nserde_json = \"1.0\" # JSON i\u015flemleri i\u00e7in\ntokio = { version = \"1.0\", features = [\"full\"] } # Asenkron i\u015flemler (PDF d\u00f6n\u00fc\u015ft\u00fcr\u00fcc\u00fc i\u00e7in gerekebilir)\nchromiumoxide = \"0.4.0\" # Headless Chrome ile PDF olu\u015fturma (alternatif olarak wkhtmltopdf de kullan\u0131labilir)\nanyhow = \"1.0\" # Hata y\u00f6netimi i\u00e7in\n<\/code><\/pre>\n<\/div>\n<p>Burada ekledi\u011fimiz ba\u011f\u0131ml\u0131l\u0131klar\u0131 k\u0131saca a\u00e7\u0131klayal\u0131m:<\/p>\n<ul>\n<li><code>tera<\/code>: Django ve Jinja2&#8217;den esinlenmi\u015f, g\u00fc\u00e7l\u00fc bir HTML \u015fablon motorudur. Dinamik verileri \u015fablonlar\u0131m\u0131za entegre etmek i\u00e7in kullanaca\u011f\u0131z. Ko\u015fullu ifadeler, d\u00f6ng\u00fcler ve makrolar gibi zengin \u00f6zellikler sunar.<\/li>\n<li><code>serde<\/code> ve <code>serde_json<\/code>: Rust&#8217;ta veri yap\u0131lar\u0131n\u0131 (struct) JSON gibi formatlara serile\u015ftirmek ve bu formatlardan deserile\u015ftirmek i\u00e7in end\u00fcstri standard\u0131 k\u00fct\u00fcphanelerdir. \u00d6\u011frenci verilerimizi \u015fablon motoruna aktar\u0131rken bu k\u00fct\u00fcphanelerden faydalanaca\u011f\u0131z. <code>features = [\"derive\"]<\/code> sayesinde <code>#[derive(Serialize, Deserialize)]<\/code> makrolar\u0131n\u0131 kullanarak veri yap\u0131lar\u0131m\u0131z\u0131 kolayca serile\u015ftirilebilir hale getirebiliriz.<\/li>\n<li><code>tokio<\/code>: Asenkron programlama i\u00e7in bir \u00e7al\u0131\u015fma zaman\u0131 (runtime). \u00d6zellikle <code>chromiumoxide<\/code> gibi k\u00fct\u00fcphanelerle \u00e7al\u0131\u015f\u0131rken, web taray\u0131c\u0131s\u0131 i\u015flemlerini e\u015fzamans\u0131z olarak y\u00f6netmek i\u00e7in gereklidir. Bu, uygulaman\u0131z\u0131n ayn\u0131 anda birden fazla raporu i\u015flemesine olanak tan\u0131r.<\/li>\n<li><code>chromiumoxide<\/code>: Rust i\u00e7in Headless Chrome\/Chromium kontrol k\u00fct\u00fcphanesidir. HTML i\u00e7eri\u011fini tam bir web taray\u0131c\u0131s\u0131 motoru kullanarak PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrmenin en g\u00fcvenilir yollar\u0131ndan biridir, \u00e7\u00fcnk\u00fc taray\u0131c\u0131lar HTML, CSS ve JavaScript&#8217;i en do\u011fru \u015fekilde yorumlar. Bu, karma\u015f\u0131k CSS d\u00fczenlerine sahip raporlar i\u00e7in idealdir. Alternatif olarak, <code>wkhtmltopdf<\/code> gibi harici bir ara\u00e7 da kullan\u0131labilir, ancak <code>chromiumoxide<\/code> daha entegre bir \u00e7\u00f6z\u00fcm sunar.<\/li>\n<li><code>anyhow<\/code>: Basit ve etkili hata y\u00f6netimi sa\u011flayan bir k\u00fct\u00fcphanedir. \u00d6zellikle prototipleme ve k\u00fc\u00e7\u00fck uygulamalarda hata d\u00f6n\u00fc\u015flerini daha okunabilir hale getirir.<\/li>\n<\/ul>\n<p>Bu ba\u011f\u0131ml\u0131l\u0131klar\u0131 ekledikten sonra, Cargo otomatik olarak bunlar\u0131 indirip projenize dahil edecektir. Art\u0131k projemiz, dinamik raporlar olu\u015fturmak ve bunlar\u0131 PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in gerekli t\u00fcm ara\u00e7lara sahip. Bir sonraki ad\u0131mda, raporlar\u0131m\u0131z i\u00e7in veri modellerini tan\u0131mlayarak bu ara\u00e7lar\u0131 kullanmaya ba\u015flayaca\u011f\u0131z.<\/p>\n<h3>\u00d6\u011frenci Veri Modellerini Tasarlama ve Y\u00f6netme<\/h3>\n<p>Raporlama sistemimizin temelini olu\u015fturan en \u00f6nemli unsurlardan biri, \u00f6\u011frenci verilerini nas\u0131l yap\u0131land\u0131rd\u0131\u011f\u0131m\u0131zd\u0131r. Rust&#8217;\u0131n g\u00fc\u00e7l\u00fc t\u00fcr sistemi, bu verileri g\u00fcvenli ve anlaml\u0131 bir \u015fekilde modellememize olanak tan\u0131r. <code>struct<\/code> yap\u0131lar\u0131n\u0131 kullanarak, bir \u00f6\u011frencinin ad\u0131, soyad\u0131, numaras\u0131, ald\u0131\u011f\u0131 dersler ve bu derslerden ald\u0131\u011f\u0131 notlar gibi bilgileri d\u00fczenli bir \u015fekilde tutabiliriz. Ayr\u0131ca, bu veri yap\u0131lar\u0131n\u0131 HTML \u015fablonlar\u0131m\u0131za aktarabilmek i\u00e7in <code>serde<\/code> k\u00fct\u00fcphanesinden faydalanaca\u011f\u0131z.<\/p>\n<p>\u00d6ncelikle, projemizin <code>src\/main.rs<\/code> dosyas\u0131na veya ayr\u0131 bir mod\u00fcl dosyas\u0131na (\u00f6rne\u011fin <code>src\/models.rs<\/code>) a\u015fa\u011f\u0131daki veri yap\u0131lar\u0131n\u0131 ekleyelim:<\/p>\n<div class=\"code-container\">\n<pre><code>use serde::Serialize; \/\/ Serile\u015ftirme \u00f6zelli\u011fi i\u00e7in\n\n#[derive(Serialize)]\npub struct DersNotu {\n    pub ders_adi: String,\n    pub kredi: u8,\n    pub vize: u8,\n    pub final_notu: u8,\n    pub harf_notu: String,\n    pub ortalama: f32,\n}\n\n#[derive(Serialize)]\npub struct Ogrenci {\n    pub ogrenci_no: String,\n    pub ad: String,\n    pub soyad: String,\n    pub sinif: u8,\n    pub dersler: Vec<DersNotu>,\n    pub genel_ort: f32,\n    pub durum: String, \/\/ Ba\u015far\u0131l\u0131, \u015eartl\u0131 Ba\u015far\u0131l\u0131, Ba\u015far\u0131s\u0131z\n}\n\n#[derive(Serialize)]\npub struct RaporVerisi {\n    pub kurum_adi: String,\n    pub donem: String,\n    pub ogrenci: Ogrenci,\n}\n<\/code><\/pre>\n<\/div>\n<p>Bu kod blo\u011funda \u00fc\u00e7 temel <code>struct<\/code> tan\u0131mlad\u0131k:<\/p>\n<ul>\n<li><code>DersNotu<\/code>: Bir \u00f6\u011frencinin ald\u0131\u011f\u0131 her bir ders i\u00e7in ayr\u0131nt\u0131l\u0131 bilgileri (ders ad\u0131, kredi, vize, final notu, harf notu ve ders ortalamas\u0131) tutar.<\/li>\n<li><code>Ogrenci<\/code>: Bir \u00f6\u011frencinin genel bilgilerini (numaras\u0131, ad\u0131, soyad\u0131, s\u0131n\u0131f\u0131) ve ald\u0131\u011f\u0131 derslerin bir listesini (<code>Vec<DersNotu><\/code>) i\u00e7erir. Ayr\u0131ca, genel not ortalamas\u0131 ve akademik durumu gibi \u00f6zet bilgileri de bar\u0131nd\u0131r\u0131r.<\/li>\n<li><code>RaporVerisi<\/code>: T\u00fcm rapor i\u00e7in gerekli olan \u00fcst d\u00fczey bilgileri (kurum ad\u0131, d\u00f6nem) ve ana <code>Ogrenci<\/code> nesnesini kapsar. Bu yap\u0131, <code>tera<\/code> \u015fablon motoruna tek bir ba\u011flam (context) olarak aktar\u0131lacak ana veri modelimizdir.<\/li>\n<\/ul>\n<p>Her bir <code>struct<\/code>&#8216;\u0131n \u00fczerinde yer alan <code>#[derive(Serialize)]<\/code> niteli\u011fi, <code>serde<\/code> k\u00fct\u00fcphanesinin sa\u011flad\u0131\u011f\u0131 bir makrodur. Bu makro sayesinde, Rust derleyicisi bu yap\u0131lar\u0131 otomatik olarak serile\u015ftirilebilir (\u00f6rne\u011fin, JSON&#8217;a d\u00f6n\u00fc\u015ft\u00fcr\u00fclebilir) hale getiren kodu olu\u015fturur. Bu, <code>tera<\/code> \u015fablon motorunun bu verileri kolayca anlay\u0131p HTML \u015fablonlar\u0131m\u0131za yerle\u015ftirebilmesi i\u00e7in hayati \u00f6neme sahiptir.<\/p>\n<p>\u015eimdi bu veri yap\u0131lar\u0131n\u0131 kullanarak \u00f6rnek bir \u00f6\u011frenci verisi olu\u015ftural\u0131m. Bu veriyi daha sonra HTML \u015fablonumuza aktaraca\u011f\u0131z:<\/p>\n<div class=\"code-container\">\n<pre><code>fn main() -> anyhow::Result<()> {\n    let ders1 = DersNotu {\n        ders_adi: \"Algoritma ve Programlama\".to_string(),\n        kredi: 5,\n        vize: 75,\n        final_notu: 80,\n        harf_notu: \"BB\".to_string(),\n        ortalama: 78.5,\n    };\n\n    let ders2 = DersNotu {\n        ders_adi: \"Veri Yap\u0131lar\u0131\".to_string(),\n        kredi: 6,\n        vize: 60,\n        final_notu: 70,\n        harf_notu: \"CC\".to_string(),\n        ortalama: 66.0,\n    };\n\n    let ogrenci = Ogrenci {\n        ogrenci_no: \"2023001\".to_string(),\n        ad: \"Ay\u015fe\".to_string(),\n        soyad: \"Y\u0131lmaz\".to_string(),\n        sinif: 2,\n        dersler: vec![ders1, ders2],\n        genel_ort: 72.25,\n        durum: \"Ba\u015far\u0131l\u0131\".to_string(),\n    };\n\n    let rapor_verisi = RaporVerisi {\n        kurum_adi: \"Geli\u015fim \u00dcniversitesi\".to_string(),\n        donem: \"2023-2024 Bahar D\u00f6nemi\".to_string(),\n        ogrenci: ogrenci,\n    };\n\n    \/\/ Bu <code>rapor_verisi<\/code> nesnesini Tera \u015fablonuna aktaraca\u011f\u0131z.\n    \/\/ ... (sonraki ad\u0131mlarda bu veriyi kullanaca\u011f\u0131z)\n\n    Ok(())\n}\n<\/code><\/pre>\n<\/div>\n<p>Bu \u00f6rnekte, manuel olarak bir \u00f6\u011frenci ve ders notu verisi olu\u015fturduk. Ger\u00e7ek d\u00fcnya senaryolar\u0131nda, bu veriler bir veritaban\u0131ndan, bir API&#8217;den veya bir CSV dosyas\u0131ndan okunarak dinamik olarak olu\u015fturulacakt\u0131r. Ancak \u015fimdilik, temel veri yap\u0131lar\u0131m\u0131z\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6stermek i\u00e7in bu manuel yakla\u015f\u0131m yeterlidir. Veri modellerimizi bu \u015fekilde tan\u0131mlamak, hem kodumuzun okunabilirli\u011fini ve bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r hem de \u015fablon motoruyla entegrasyonu sorunsuz hale getirir. Art\u0131k verilerimiz haz\u0131r oldu\u011funa g\u00f6re, bir sonraki ad\u0131mda bu verileri g\u00f6rselle\u015ftirece\u011fimiz HTML \u015fablonunu haz\u0131rlayabiliriz.<\/p>\n<h3>Dinamik HTML \u015eablonlar\u0131 ile Rapor Tasar\u0131m\u0131 Nas\u0131l Yap\u0131l\u0131r?<\/h3>\n<p>Veri modellerimizi Rust&#8217;ta tan\u0131mlad\u0131ktan sonra, s\u0131ra bu verileri g\u00f6rsel olarak \u00e7ekici ve okunabilir bir rapora d\u00f6n\u00fc\u015ft\u00fcrecek HTML \u015fablonunu haz\u0131rlamaya geldi. Bu a\u015famada, Rust&#8217;\u0131n g\u00fc\u00e7l\u00fc \u015fablon motoru <code>tera<\/code>&#8216;dan faydalanaca\u011f\u0131z. Tera, Django ve Jinja2 gibi pop\u00fcler \u015fablon dillerinden esinlenerek geli\u015ftirilmi\u015f olup, ko\u015fullu ifadeler, d\u00f6ng\u00fcler ve de\u011fi\u015fken entegrasyonu gibi zengin \u00f6zellikler sunar.<\/p>\n<p>\u00d6ncelikle, projemizin k\u00f6k dizininde veya belirlenmi\u015f bir klas\u00f6rde (\u00f6rne\u011fin <code>templates\/<\/code>) bir HTML \u015fablon dosyas\u0131 olu\u015ftural\u0131m. Ad\u0131n\u0131 <code>ogrenci_raporu.html<\/code> koyabiliriz.<\/p>\n<div class=\"code-container\">\n<\/div>\n<p>Yukar\u0131daki HTML \u015fablonunda, <code>{{ degisken_adi }}<\/code> format\u0131nda Tera de\u011fi\u015fkenlerini g\u00f6receksiniz. Bu de\u011fi\u015fkenler, Rust kodumuzdan aktaraca\u011f\u0131m\u0131z <code>RaporVerisi<\/code> yap\u0131s\u0131n\u0131n alanlar\u0131na kar\u015f\u0131l\u0131k gelir. \u00d6rne\u011fin, <code>{{ ogrenci.ad }}<\/code> ifadesi, <code>RaporVerisi.ogrenci.ad<\/code> alan\u0131ndaki de\u011feri al\u0131p buraya yerle\u015ftirecektir.<\/p>\n<p>\u015eablonun \u00f6nemli k\u0131s\u0131mlar\u0131:<\/p>\n<ul>\n<li><strong>D\u00f6ng\u00fcler (<code>{% for ... in ... %}<\/code>):<\/strong> <code>ogrenci.dersler<\/code> listesi \u00fczerinde bir d\u00f6ng\u00fc kurarak her bir dersin bilgilerini tabloya dinamik olarak ekliyoruz. Bu, ka\u00e7 ders olursa olsun raporun do\u011fru \u015fekilde olu\u015fturulmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Ko\u015fullu \u0130fadeler (<code>{% if ... %}<\/code>):<\/strong> \u00d6\u011frencinin akademik durumuna g\u00f6re metin rengini de\u011fi\u015ftirmek gibi ko\u015fullu bi\u00e7imlendirmeler yapabiliriz. Bu sayede, raporlar daha g\u00f6rsel ve anlaml\u0131 hale gelir.<\/li>\n<li><strong>Filtreler (<code>| float_format(2)<\/code>):<\/strong> Say\u0131sal de\u011ferleri bi\u00e7imlendirmek i\u00e7in filtreler kullanabiliriz. \u00d6rne\u011fin, <code>float_format(2)<\/code> ondal\u0131k say\u0131y\u0131 iki basama\u011fa yuvarlar. Tera, tarih bi\u00e7imlendirme, metin manip\u00fclasyonu gibi bir\u00e7ok yerle\u015fik filtre sunar.<\/li>\n<li><strong>Fonksiyonlar (<code>{{ now() }}<\/code>):<\/strong> \u015eablon i\u00e7inde tarih ve saat gibi baz\u0131 yard\u0131mc\u0131 fonksiyonlar\u0131 \u00e7a\u011f\u0131rabiliriz.<\/li>\n<li><strong>CSS Stili:<\/strong> <code>&lt;style&gt;<\/code> etiketi i\u00e7inde temel CSS tan\u0131mlamalar\u0131 yer almaktad\u0131r. Bu stiller, raporun genel g\u00f6r\u00fcn\u00fcm\u00fcn\u00fc ve okunabilirli\u011fini art\u0131r\u0131r. Ger\u00e7ek bir uygulamada, bu stiller ayr\u0131 bir <code>.css<\/code> dosyas\u0131nda tutulup \u015fablona ba\u011flanabilir. PDF d\u00f6n\u00fc\u015f\u00fcm ara\u00e7lar\u0131 genellikle bu t\u00fcr g\u00f6m\u00fcl\u00fc stilleri sorunsuz bir \u015fekilde i\u015fler.<\/li>\n<\/ul>\n<p>Bu \u015fablon, temel bir \u00f6\u011frenci not d\u00f6k\u00fcm\u00fc raporu i\u00e7in yeterli bir ba\u015flang\u0131\u00e7 noktas\u0131d\u0131r. Kurumunuzun ihtiya\u00e7lar\u0131na g\u00f6re logo ekleme, daha detayl\u0131 tablo yap\u0131lar\u0131, grafikler (JavaScript k\u00fct\u00fcphaneleri ile olu\u015fturulup statik resim olarak g\u00f6m\u00fclerek) veya ek bilgilendirme b\u00f6l\u00fcmleri gibi geli\u015ftirmeler yapabilirsiniz. \u015eablonun esnekli\u011fi, raporlar\u0131n\u0131z\u0131n her zaman g\u00fcncel ve profesyonel g\u00f6r\u00fcnmesini sa\u011flar. \u015eimdi, bu \u015fablonu Rust kodumuzda nas\u0131l kullanaca\u011f\u0131m\u0131za ge\u00e7ebiliriz.<\/p>\n<h3>Rust ile HTML \u015eablonunu Doldurma ve PDF&#8217;e D\u00f6n\u00fc\u015ft\u00fcrme<\/h3>\n<p>\u015eimdiye kadar veri modellerimizi tan\u0131mlad\u0131k ve dinamik bir HTML \u015fablonu haz\u0131rlad\u0131k. Bu b\u00f6l\u00fcmde, Rust kodumuzda bu iki par\u00e7ay\u0131 bir araya getirecek ve son olarak ortaya \u00e7\u0131kan HTML \u00e7\u0131kt\u0131s\u0131n\u0131 bir PDF dosyas\u0131na d\u00f6n\u00fc\u015ft\u00fcrece\u011fiz. Bu i\u015flem i\u00e7in <code>tera<\/code> k\u00fct\u00fcphanesini HTML \u015fablonlar\u0131n\u0131 i\u015flemek ve <code>chromiumoxide<\/code> k\u00fct\u00fcphanesini (veya <code>wkhtmltopdf<\/code> gibi harici bir arac\u0131) PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in kullanaca\u011f\u0131z.<\/p>\n<p>\u00d6ncelikle, <code>src\/main.rs<\/code> dosyam\u0131z\u0131 g\u00fcncelleyelim. Tera&#8217;y\u0131 ba\u015flatmak ve \u015fablonumuzu y\u00fcklemek i\u00e7in a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 izleyece\u011fiz:<\/p>\n<div class=\"code-container\">\n<pre><code>use tera::{Context, Tera};\nuse serde::Serialize;\nuse anyhow::Result;\nuse tokio;\nuse chromiumoxide::browser::{Browser, BrowserConfig};\nuse chromiumoxide::page::Page;\n\n\/\/ Veri modellerimiz (DersNotu, Ogrenci, RaporVerisi) burada tan\u0131mlanm\u0131\u015f olmal\u0131.\n\/\/ \u00d6nceki b\u00f6l\u00fcmden kopyalay\u0131p buraya yap\u0131\u015ft\u0131rabilirsiniz.\n#[derive(Serialize)]\npub struct DersNotu {\n    pub ders_adi: String,\n    pub kredi: u8,\n    pub vize: u8,\n    pub final_notu: u8,\n    pub harf_notu: String,\n    pub ortalama: f32,\n}\n\n#[derive(Serialize)]\npub struct Ogrenci {\n    pub ogrenci_no: String,\n    pub ad: String,\n    pub soyad: String,\n    pub sinif: u8,\n    pub dersler: Vec<DersNotu>,\n    pub genel_ort: f32,\n    pub durum: String,\n}\n\n#[derive(Serialize)]\npub struct RaporVerisi {\n    pub kurum_adi: String,\n    pub donem: String,\n    pub ogrenci: Ogrenci,\n}\n\n#[tokio::main]\nasync fn main() -> Result<()> {\n    \/\/ 1. Tera \u015eablon Motorunu Ba\u015flatma\n    \/\/ \u015eablon dosyalar\u0131n\u0131n 'templates' klas\u00f6r\u00fc alt\u0131nda oldu\u011funu varsay\u0131yoruz.\n    let mut tera = Tera::new(\"templates\/**\/*.html\")?;\n    \/\/ \u015eablonlar\u0131 yeniden y\u00fcklemeyi etkinle\u015ftirin (geli\u015ftirme s\u0131ras\u0131nda faydal\u0131)\n    tera.autoescape_on(vec![\".html\"]); \/\/ HTML \u015fablonlar\u0131 i\u00e7in otomatik ka\u00e7\u0131\u015f\u0131 etkinle\u015ftir\n    tera.register_function(\"now\", |args| { \/\/ <code>now()<\/code> fonksiyonunu \u015fablona ekle\n        let dt = chrono::Local::now();\n        let format = args.get(\"format\").and_then(|v| v.as_str()).unwrap_or(\"%Y-%m-%d %H:%M:%S\");\n        Ok(tera::to_value(dt.format(format).to_string())?)\n    });\n    \/\/ float_format filtresini manuel olarak ekleyebiliriz veya Tera'n\u0131n varsay\u0131lan filtrelerini kullanabiliriz\n    \/\/ Tera'da <code>float_format<\/code> varsay\u0131lan olarak yoktur, ancak kendi filtrenizi yazabilirsiniz.\n    \/\/ \u015eimdilik, \u015fablonda <code>| round(2)<\/code> veya benzeri bir filtre kullanmak daha kolay olacakt\u0131r.\n    \/\/ Veya Tera'n\u0131n <code>number_format<\/code> filtresini kullanabiliriz: <code>{{ ogrenci.genel_ort | number_format(2, decimal=&#039;.&#039;, thousands=&#039;,&#039;) }}<\/code>\n\n    \/\/ 2. \u00d6rnek Veri Olu\u015fturma (\u00f6nceki b\u00f6l\u00fcmden)\n    let ders1 = DersNotu {\n        ders_adi: \"Algoritma ve Programlama\".to_string(),\n        kredi: 5,\n        vize: 75,\n        final_notu: 80,\n        harf_notu: \"BB\".to_string(),\n        ortalama: 78.5,\n    };\n\n    let ders2 = DersNotu {\n        ders_adi: \"Veri Yap\u0131lar\u0131\".to_string(),\n        kredi: 6,\n        vize: 60,\n        final_notu: 70,\n        harf_notu: \"CC\".to_string(),\n        ortalama: 66.0,\n    };\n\n    let ogrenci = Ogrenci {\n        ogrenci_no: \"2023001\".to_string(),\n        ad: \"Ay\u015fe\".to_string(),\n        soyad: \"Y\u0131lmaz\".to_string(),\n        sinif: 2,\n        dersler: vec![ders1, ders2],\n        genel_ort: 72.25,\n        durum: \"Ba\u015far\u0131l\u0131\".to_string(),\n    };\n\n    let rapor_verisi = RaporVerisi {\n        kurum_adi: \"Geli\u015fim \u00dcniversitesi\".to_string(),\n        donem: \"2023-2024 Bahar D\u00f6nemi\".to_string(),\n        ogrenci: ogrenci,\n    };\n\n    \/\/ 3. Veriyi Tera Context'ine D\u00f6n\u00fc\u015ft\u00fcrme\n    let context = Context::from_serialize(&rapor_verisi)?;\n\n    \/\/ 4. \u015eablonu \u0130\u015fleme ve HTML \u00c7\u0131kt\u0131s\u0131 Alma\n    let rendered_html = tera.render(\"ogrenci_raporu.html\", &context)?;\n    println!(\"HTML ba\u015far\u0131yla olu\u015fturuldu.\");\n    \n    \/\/ Olu\u015fturulan HTML'i bir dosyaya kaydet (iste\u011fe ba\u011fl\u0131, hata ay\u0131klama i\u00e7in)\n    tokio::fs::write(\"output_rapor.html\", &rendered_html).await?;\n\n    \/\/ 5. HTML'i PDF'e D\u00f6n\u00fc\u015ft\u00fcrme (chromiumoxide kullanarak)\n    \/\/ Headless Chrome'u ba\u015flatma\n    let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?;\n    let handle = tokio::task::spawn(async move {\n        loop {\n            let _ = handler.next().await.unwrap();\n        }\n    });\n\n    \/\/ Yeni bir sayfa a\u00e7ma\n    let page = browser.new_page(\"about:blank\").await?;\n\n    \/\/ Olu\u015fturulan HTML'i sayfaya y\u00fckleme\n    page.set_content(rendered_html).await?;\n\n    \/\/ PDF se\u00e7eneklerini belirleme\n    let pdf_options = chromiumoxide::page::print_to_pdf::PrintToPdfOptions::builder()\n        .format(chromiumoxide::page::print_to_pdf::PaperFormat::A4)\n        .print_background(true) \/\/ Arka plan renklerini\/resimlerini yazd\u0131r\n        .build();\n\n    \/\/ PDF'i olu\u015fturma ve kaydetme\n    let pdf_bytes = page.print_to_pdf(pdf_options).await?.expect(\"PDF olu\u015fturulamad\u0131.\");\n    tokio::fs::write(format!(\"rapor_{}.pdf\", rapor_verisi.ogrenci.ogrenci_no), pdf_bytes).await?;\n\n    println!(\"PDF ba\u015far\u0131yla olu\u015fturuldu ve kaydedildi.\");\n\n    \/\/ Taray\u0131c\u0131y\u0131 kapatma\n    browser.close().await?;\n    handle.abort(); \/\/ handler g\u00f6revini iptal et\n\n    Ok(())\n}\n<\/code><\/pre>\n<\/div>\n<p>Bu kod blo\u011fu, rapor olu\u015fturma s\u00fcrecinin tamam\u0131n\u0131 kapsar:<\/p>\n<ol>\n<li><strong>Tera Ba\u015flatma<\/strong>: <code>Tera::new(\"templates\/**\/*.html\")?<\/code> ifadesi, <code>templates<\/code> dizini alt\u0131ndaki t\u00fcm HTML dosyalar\u0131n\u0131 \u015fablon olarak kaydeder. <code>autoescape_on<\/code> ile g\u00fcvenlik \u00f6nlemi al\u0131n\u0131r. <code>register_function<\/code> ile \u015fablonda kullan\u0131labilecek \u00f6zel bir <code>now()<\/code> fonksiyonu ekledik.<\/li>\n<li><strong>Veri Olu\u015fturma<\/strong>: \u00d6nceki b\u00f6l\u00fcmde tan\u0131mlad\u0131\u011f\u0131m\u0131z <code>RaporVerisi<\/code> yap\u0131s\u0131n\u0131 kullanarak \u00f6rnek bir veri seti olu\u015fturulur. Ger\u00e7ek senaryolarda bu veri, bir veritaban\u0131ndan veya ba\u015fka bir kaynaktan al\u0131nacakt\u0131r.<\/li>\n<li><strong>Context Olu\u015fturma<\/strong>: <code>Context::from_serialize(&rapor_verisi)?<\/code> ile Rust&#8217;taki veri yap\u0131m\u0131z, Tera&#8217;n\u0131n anlayabilece\u011fi bir ba\u011flama (context) d\u00f6n\u00fc\u015ft\u00fcr\u00fcl\u00fcr. Bu sayede \u015fablondaki de\u011fi\u015fkenler, bu ba\u011flamdaki de\u011ferlerle doldurulur.<\/li>\n<li><strong>HTML Olu\u015fturma<\/strong>: <code>tera.render(\"ogrenci_raporu.html\", &context)?<\/code> \u00e7a\u011fr\u0131s\u0131, belirtilen \u015fablonu (<code>ogrenci_raporu.html<\/code>) verilen ba\u011flamla i\u015fler ve dinamik HTML \u00e7\u0131kt\u0131s\u0131n\u0131 bir <code>String<\/code> olarak d\u00f6nd\u00fcr\u00fcr. Bu HTML \u00e7\u0131kt\u0131s\u0131n\u0131 bir dosyaya kaydederek do\u011fru olu\u015fturulup olu\u015fturulmad\u0131\u011f\u0131n\u0131 kontrol edebilirsiniz.<\/li>\n<li><strong>PDF D\u00f6n\u00fc\u015f\u00fcm\u00fc<\/strong>:\n<ul>\n<li><code>chromiumoxide::browser::Browser::launch<\/code> ile Headless Chrome\/Chromium taray\u0131c\u0131 \u00f6rne\u011fi ba\u015flat\u0131l\u0131r. Bu, sisteminizde kurulu bir Chrome\/Chromium taray\u0131c\u0131s\u0131n\u0131n arka planda \u00e7al\u0131\u015fmas\u0131n\u0131 gerektirir.<\/li>\n<li><code>browser.new_page(\"about:blank\").await?<\/code> ile bo\u015f bir taray\u0131c\u0131 sayfas\u0131 a\u00e7\u0131l\u0131r.<\/li>\n<li><code>page.set_content(rendered_html).await?<\/code> ile Tera taraf\u0131ndan olu\u015fturulan HTML i\u00e7eri\u011fi bu sayfaya y\u00fcklenir. Taray\u0131c\u0131, HTML&#8217;i ve CSS&#8217;i yorumlayarak sayfay\u0131 ekranda g\u00f6r\u00fcnd\u00fc\u011f\u00fc gibi haz\u0131rlar.<\/li>\n<li><code>page.print_to_pdf(pdf_options).await?<\/code> \u00e7a\u011fr\u0131s\u0131, sayfan\u0131n i\u00e7eri\u011fini belirtilen se\u00e7eneklerle (\u00f6rne\u011fin A4 boyutu, arka plan\u0131n yazd\u0131r\u0131lmas\u0131) PDF format\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fcr.<\/li>\n<li>Son olarak, elde edilen PDF baytlar\u0131 <code>tokio::fs::write<\/code> ile bir dosyaya kaydedilir. \u00d6\u011frenci numaras\u0131na g\u00f6re dinamik bir dosya ad\u0131 olu\u015fturulur.<\/li>\n<li>\u0130\u015flem bittikten sonra taray\u0131c\u0131 kapat\u0131l\u0131r.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Bu y\u00f6ntem, karma\u015f\u0131k CSS ve hatta baz\u0131 JavaScript (PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclmeden \u00f6nce \u00e7al\u0131\u015fmas\u0131 gerekenler) i\u00e7eren raporlar i\u00e7in en do\u011fru PDF \u00e7\u0131kt\u0131s\u0131n\u0131 sa\u011flar, \u00e7\u00fcnk\u00fc ger\u00e7ek bir taray\u0131c\u0131 motoru kullan\u0131r. E\u011fer sisteminizde Headless Chrome kurmak veya y\u00f6netmek istemezseniz, <code>wkhtmltopdf<\/code> gibi harici bir komut sat\u0131r\u0131 arac\u0131n\u0131 Rust&#8217;tan \u00e7al\u0131\u015ft\u0131rmak da bir alternatif olabilir. Ancak <code>chromiumoxide<\/code> daha entegre ve kontrol edilebilir bir \u00e7\u00f6z\u00fcm sunar. Bu ad\u0131mlarla, dinamik \u00f6\u011frenci raporlar\u0131n\u0131z\u0131 Rust ile ba\u015far\u0131yla olu\u015fturup PDF format\u0131nda d\u0131\u015fa aktarabilirsiniz.<\/p>\n<h3>Vaka Analizi: B\u00fcy\u00fck \u00d6l\u00e7ekli Rapor Olu\u015fturma ve Performans Optimizasyonu<\/h3>\n<p>Bir \u00fcniversitenin d\u00f6nem sonunda yakla\u015f\u0131k 15.000 \u00f6\u011frencisi i\u00e7in not d\u00f6k\u00fcm\u00fc raporu olu\u015fturmas\u0131 gerekti\u011fini d\u00fc\u015f\u00fcnelim. Her \u00f6\u011frencinin ortalama 10 dersi ve bu derslere ait vize, final, harf notu gibi detaylar\u0131 bulunuyor. Bu kadar b\u00fcy\u00fck bir veri setini h\u0131zl\u0131, g\u00fcvenli ve hatas\u0131z bir \u015fekilde i\u015fleyip PDF raporlar\u0131 haline getirmek, geleneksel y\u00f6ntemlerle olduk\u00e7a zorlay\u0131c\u0131 olabilir. \u0130\u015fte bu senaryoda Rust ve yukar\u0131da anlatt\u0131\u011f\u0131m\u0131z yakla\u015f\u0131m, nas\u0131l bir \u00e7\u00f6z\u00fcm sunar?<\/p>\n<p><strong>Mevcut Durum ve Zorluklar:<\/strong><br \/>\nGeleneksel olarak, bir\u00e7ok e\u011fitim kurumu raporlar\u0131 ya manuel olarak (her \u00f6\u011frenci i\u00e7in ayr\u0131 ayr\u0131 Word veya Excel dosyalar\u0131 d\u00fczenleyerek) ya da eski, monolitik sistemler \u00fczerinden (genellikle performans sorunlar\u0131 ya\u015fayan veya esnek olmayan) olu\u015fturur. Bu durumlar, \u00f6zellikle d\u00f6nem sonu gibi yo\u011fun zamanlarda a\u015fa\u011f\u0131daki sorunlara yol a\u00e7ar:<\/p>\n<ul>\n<li><strong>Zaman Kayb\u0131:<\/strong> On binlerce raporun tek tek haz\u0131rlanmas\u0131 g\u00fcnler, hatta haftalar s\u00fcrebilir.<\/li>\n<li><strong>\u0130nsan Hatas\u0131:<\/strong> Veri giri\u015finde veya \u015fablon d\u00fczenlemelerinde yap\u0131lan hatalar, \u00f6\u011frencilere yanl\u0131\u015f bilgi ula\u015fmas\u0131na neden olabilir.<\/li>\n<li><strong>Kaynak Yo\u011funlu\u011fu:<\/strong> Eski sistemler, rapor olu\u015fturma s\u0131ras\u0131nda sunucular\u0131 a\u015f\u0131r\u0131 y\u00fckleyebilir, di\u011fer hizmetleri yava\u015flatabilir.<\/li>\n<li><strong>\u00d6l\u00e7eklenebilirlik Eksikli\u011fi:<\/strong> \u00d6\u011frenci say\u0131s\u0131 artt\u0131k\u00e7a sistemin ba\u015fa \u00e7\u0131kma kapasitesi azal\u0131r.<\/li>\n<li><strong>Esneklik Eksikli\u011fi:<\/strong> Rapor format\u0131nda yap\u0131lacak de\u011fi\u015fiklikler, yaz\u0131l\u0131m ekibinden b\u00fcy\u00fck \u00e7aba ve zaman gerektirebilir.<\/li>\n<\/ul>\n<p><strong>Rust Tabanl\u0131 \u00c7\u00f6z\u00fcm\u00fcn Uygulanmas\u0131:<\/strong><br \/>\n\u00dcniversite, mevcut \u00f6\u011frenci ve ders verilerini bir veritaban\u0131nda (\u00f6rne\u011fin PostgreSQL) tutuyor. Rust tabanl\u0131 raporlama sistemi, bu veritaban\u0131ndan asenkron olarak (<code>tokio-postgres<\/code> veya <code>sqlx<\/code> gibi k\u00fct\u00fcphanelerle) verileri \u00e7eker. Her \u00f6\u011frenci i\u00e7in <code>Ogrenci<\/code> ve <code>DersNotu<\/code> yap\u0131lar\u0131 olu\u015fturulur. Bu s\u00fcre\u00e7, Rust&#8217;\u0131n e\u015fzamanl\u0131 (concurrent) ve paralel i\u015fleme yetenekleri sayesinde olduk\u00e7a h\u0131zl\u0131d\u0131r. \u00d6rne\u011fin, <code>tokio::spawn<\/code> kullanarak birden fazla \u00f6\u011frenci raporunu ayn\u0131 anda i\u015flemek \u00fczere g\u00f6revler (task) ba\u015flat\u0131labilir.<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ \u00d6rnek: Birden fazla raporu paralel olarak olu\u015fturma\nasync fn generate_all_reports(students_data: Vec<Ogrenci>, tera: Arc<Tera>, browser: Arc<Browser>) -> Result<()> {\n    let mut tasks = Vec::new();\n    for student in students_data {\n        let tera_clone = Arc::clone(&tera);\n        let browser_clone = Arc::clone(&browser);\n        let student_no = student.ogrenci_no.clone();\n\n        tasks.push(tokio::spawn(async move {\n            let rapor_verisi = RaporVerisi {\n                kurum_adi: \"Geli\u015fim \u00dcniversitesi\".to_string(),\n                donem: \"2023-2024 Bahar D\u00f6nemi\".to_string(),\n                ogrenci: student,\n            };\n            let context = Context::from_serialize(&rapor_verisi)?;\n            let rendered_html = tera_clone.render(\"ogrenci_raporu.html\", &context)?;\n\n            let page = browser_clone.new_page(\"about:blank\").await?;\n            page.set_content(rendered_html).await?;\n            let pdf_options = chromiumoxide::page::print_to_pdf::PrintToPdfOptions::builder()\n                .format(chromiumoxide::page::print_to_pdf::PaperFormat::A4)\n                .print_background(true)\n                .build();\n            let pdf_bytes = page.print_to_pdf(pdf_options).await?.expect(\"PDF olu\u015fturulamad\u0131.\");\n            tokio::fs::write(format!(\"rapor_{}.pdf\", student_no), pdf_bytes).await?;\n            println!(\"Rapor {} i\u00e7in PDF olu\u015fturuldu.\", student_no);\n            Ok::<(), anyhow::Error>(())\n        }));\n    }\n\n    for task in tasks {\n        task.await??; \/\/ Her g\u00f6revin tamamlanmas\u0131n\u0131 bekle ve hatalar\u0131 i\u015fle\n    }\n    Ok(())\n}\n<\/code><\/pre>\n<\/div>\n<p>Bu yap\u0131, her \u00f6\u011frenci raporu i\u00e7in ayr\u0131 bir asenkron g\u00f6rev ba\u015flat\u0131r. <code>chromiumoxide<\/code> ile Headless Chrome \u00f6rne\u011fi, birden fazla sekme (sayfa) a\u00e7arak e\u015f zamanl\u0131 PDF d\u00f6n\u00fc\u015f\u00fcmlerini destekleyebilir. Bu sayede, 15.000 \u00f6\u011frenci raporu, tek tek s\u0131ral\u0131 olarak i\u015flenmek yerine, sistemin \u00e7ekirdek say\u0131s\u0131na ve bellek kapasitesine ba\u011fl\u0131 olarak ayn\u0131 anda y\u00fczlerce rapor i\u015flenebilir.<\/p>\n<p><strong>Performans Optimizasyonlar\u0131 ve Sonu\u00e7lar:<\/strong><\/p>\n<ol>\n<li><strong>Paralel Veri \u00c7ekme:<\/strong> Veritaban\u0131ndan \u00f6\u011frenci verileri, toplu sorgular (batch queries) veya paralel ba\u011flant\u0131larla daha h\u0131zl\u0131 \u00e7ekilebilir.<\/li>\n<li><strong>Asenkron \u0130\u015fleme:<\/strong> <code>tokio<\/code> ve <code>async\/await<\/code> yap\u0131s\u0131, I\/O (giri\u015f\/\u00e7\u0131k\u0131\u015f) yo\u011fun i\u015flemlerin (veritaban\u0131, dosya yazma, a\u011f ileti\u015fimi) bloklanmadan \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. Bu, CPU&#8217;nun bo\u015f kalmamas\u0131n\u0131 ve sistem kaynaklar\u0131n\u0131n daha verimli kullan\u0131lmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Headless Chrome Havuzu:<\/strong> E\u011fer <code>chromiumoxide<\/code> ile tek bir taray\u0131c\u0131 \u00f6rne\u011fi yerine birden fazla Headless Chrome \u00f6rne\u011fi (veya taray\u0131c\u0131 havuzu) y\u00f6netilebilirse, PDF d\u00f6n\u00fc\u015f\u00fcm h\u0131z\u0131 daha da art\u0131r\u0131labilir.<\/li>\n<li><strong>\u00d6nbellekleme (Caching):<\/strong> E\u011fer raporlarda tekrarlayan statik k\u0131s\u0131mlar varsa (\u00f6rne\u011fin kurum logosu, sabit metinler), bunlar \u00f6nbelle\u011fe al\u0131narak her rapor i\u00e7in yeniden i\u015flenmesi engellenebilir.<\/li>\n<li><strong>Bellek Y\u00f6netimi:<\/strong> Rust&#8217;\u0131n bellek g\u00fcvenli\u011fi garantileri, b\u00fcy\u00fck veri setleriyle \u00e7al\u0131\u015f\u0131rken bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 ve di\u011fer bellek hatalar\u0131n\u0131 \u00f6nler, bu da uygulaman\u0131n uzun s\u00fcreli \u00e7al\u0131\u015fmalarda dahi kararl\u0131 kalmas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ol>\n<p>Bu optimizasyonlarla, 15.000 \u00f6\u011frenci raporunun olu\u015fturulmas\u0131 ve PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesi, saatler s\u00fcren bir i\u015flemden dakikalara inebilir. \u00d6rne\u011fin, iyi optimize edilmi\u015f bir sistemde, her raporun olu\u015fturulmas\u0131 ve PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesi ortalama 1-2 saniye s\u00fcrse, paralel i\u015fleme sayesinde toplam s\u00fcre \u00e7ok daha k\u0131sal\u0131r. 15.000 rapor, ortalama 15-20 dakikada tamamen olu\u015fturulup kullan\u0131ma haz\u0131r hale gelebilir. Bu, \u00fcniversite y\u00f6netimi i\u00e7in devrim niteli\u011finde bir h\u0131zlanma ve verimlilik art\u0131\u015f\u0131 anlam\u0131na gelir. Ayr\u0131ca, HTML \u015fablonlar\u0131n\u0131n kullan\u0131lmas\u0131, rapor format\u0131nda yap\u0131lacak de\u011fi\u015fikliklerin kolayca uygulanabilmesini sa\u011flayarak esneklik sorununu da ortadan kald\u0131r\u0131r. Bu vaka analizi, Rust&#8217;\u0131n ger\u00e7ek d\u00fcnya senaryolar\u0131nda nas\u0131l b\u00fcy\u00fck \u00f6l\u00e7ekli ve performans odakl\u0131 \u00e7\u00f6z\u00fcmler sunabilece\u011fini a\u00e7\u0131k\u00e7a g\u00f6stermektedir.<\/p>\n<h3>\u0130leri D\u00fczey \u0130pu\u00e7lar\u0131 ve Entegrasyon Senaryolar\u0131<\/h3>\n<p>\u015eimdiye kadar temel bir \u00f6\u011frenci raporu olu\u015fturma ve PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrme s\u00fcrecini ele ald\u0131k. Ancak Rust ile bu sistemi daha da ileriye ta\u015f\u0131yabilir, daha karma\u015f\u0131k senaryolara entegre edebiliriz. \u0130\u015fte deneyimli kullan\u0131c\u0131lar i\u00e7in baz\u0131 ileri d\u00fczey ipu\u00e7lar\u0131 ve entegrasyon senaryolar\u0131:<\/p>\n<h4>1. Raporlama Sistemini Bir Web Servisi Olarak Sunma<\/h4>\n<p>Olu\u015fturdu\u011fumuz raporlama mant\u0131\u011f\u0131n\u0131, <code>Actix-web<\/code> veya <code>Warp<\/code> gibi Rust web framework&#8217;leri ile bir RESTful API olarak sunabiliriz. Bu sayede, farkl\u0131 uygulamalar (\u00f6rne\u011fin, bir \u00f6\u011frenci bilgi sistemi veya bir web portal\u0131) bu API&#8217;yi \u00e7a\u011f\u0131rarak dinamik olarak rapor talebinde bulunabilir. \u00d6rne\u011fin, bir API u\u00e7 noktas\u0131 <code>\/api\/rapor\/ogrenci\/{ogrenci_no}<\/code> \u015feklinde tan\u0131mlanabilir. Bu u\u00e7 nokta, gelen \u00f6\u011frenci numaras\u0131na g\u00f6re veritaban\u0131ndan ilgili \u00f6\u011frencinin bilgilerini \u00e7eker, raporu olu\u015fturur ve PDF dosyas\u0131n\u0131 HTTP yan\u0131t\u0131 olarak d\u00f6ner. Bu yakla\u015f\u0131m, raporlama hizmetini merkezi hale getirir ve farkl\u0131 platformlar taraf\u0131ndan kolayca eri\u015filebilir k\u0131lar.<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ \u00d6rnek Actix-web entegrasyonu (basitle\u015ftirilmi\u015f)\n\/\/ ... (Tera ve Browser ba\u015flatma main fonksiyonunda)\n\n#[actix_web::post(\"\/rapor_olustur\")]\nasync fn rapor_olustur_endpoint(\n    req: web::Json<OgrenciRequest>, \/\/ JSON body'den \u00f6\u011frenci bilgisi al\n    app_data: web::Data<AppState>, \/\/ Tera ve Browser gibi payla\u015f\u0131lan state\n) -> Result<HttpResponse, Error> {\n    \/\/ ... (req.ogrenci_no ile veritaban\u0131ndan veri \u00e7ekme)\n    let ogrenci_data = app_data.db_client.get_ogrenci_data(req.ogrenci_no).await?;\n\n    let rapor_verisi = RaporVerisi { \/* ... *\/ ogrenci: ogrenci_data };\n    let context = Context::from_serialize(&rapor_verisi)?;\n    let rendered_html = app_data.tera.render(\"ogrenci_raporu.html\", &context)?;\n\n    let page = app_data.browser.new_page(\"about:blank\").await?;\n    page.set_content(rendered_html).await?;\n    let pdf_bytes = page.print_to_pdf(Default::default()).await?.expect(\"PDF olu\u015fturulamad\u0131.\");\n\n    Ok(HttpResponse::Ok()\n        .content_type(\"application\/pdf\")\n        .body(pdf_bytes))\n}\n\n\/\/ fn main() {\n\/\/     HttpServer::new(|| {\n\/\/         App::new()\n\/\/             .app_data(web::Data::new(AppState { \/* ... *\/ }))\n\/\/             .service(rapor_olustur_endpoint)\n\/\/     })\n\/\/     .bind(\"127.0.0.1:8080\")?\n\/\/     .run()\n\/\/     .await\n\/\/ }\n<\/code><\/pre>\n<\/div>\n<h4>2. Asenkron Kuyruklar ve Arka Plan \u0130\u015fleme<\/h4>\n<p>B\u00fcy\u00fck \u00f6l\u00e7ekli rapor talepleri i\u00e7in (\u00f6rne\u011fin, bir d\u00f6nemin t\u00fcm \u00f6\u011frencileri i\u00e7in toplu rapor olu\u015fturma), web servisinin do\u011frudan PDF d\u00f6n\u00fc\u015ft\u00fcrme i\u015flemini yapmas\u0131 sunucuyu yava\u015flatabilir. Bunun yerine, rapor olu\u015fturma taleplerini bir mesaj kuyru\u011funa (\u00f6rne\u011fin, RabbitMQ, Kafka veya Redis tabanl\u0131 bir kuyruk sistemi) g\u00f6nderebiliriz. Ayr\u0131 bir Rust i\u015f\u00e7i uygulamas\u0131 (worker application), bu kuyruktaki mesajlar\u0131 dinler, raporlar\u0131 arka planda olu\u015fturur ve PDF&#8217;leri bir dosya depolama alan\u0131na (\u00f6rne\u011fin, Amazon S3 veya yerel disk) kaydeder. Rapor haz\u0131r oldu\u011funda, kullan\u0131c\u0131ya bir bildirim g\u00f6nderilebilir veya indirme ba\u011flant\u0131s\u0131 sa\u011flanabilir. Bu mimari, sistemin \u00f6l\u00e7eklenebilirli\u011fini ve yan\u0131t verme s\u00fcresini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde art\u0131r\u0131r.<\/p>\n<h4>3. Dinamik \u015eablon Se\u00e7imi ve \u00d6zelle\u015ftirme<\/h4>\n<p>Farkl\u0131 rapor t\u00fcrleri (not d\u00f6k\u00fcm\u00fc, ba\u015far\u0131 belgesi, disiplin raporu) i\u00e7in birden fazla HTML \u015fablonu kullanabiliriz. Kullan\u0131c\u0131dan gelen talebe g\u00f6re uygun \u015fablonu se\u00e7ip i\u015fleyebiliriz. Ayr\u0131ca, \u015fablonlara dinamik olarak eklenebilecek ek alanlar (custom fields) veya kurum logosu gibi \u00f6zelle\u015ftirme se\u00e7enekleri sunabiliriz. Bu, raporlama sistemini daha esnek ve farkl\u0131 ihtiya\u00e7lara uyarlanabilir hale getirir. \u00d6rne\u011fin, <code>RaporVerisi<\/code> yap\u0131s\u0131na ek bir <code>HashMap<String, String><\/code> ekleyerek dinamik alanlar tan\u0131mlanabilir.<\/p>\n<h4>4. Hata Y\u00f6netimi ve Loglama<\/h4>\n<p>\u00dcretim ortam\u0131nda \u00e7al\u0131\u015fan bir sistemde, kapsaml\u0131 hata y\u00f6netimi ve loglama kritik \u00f6neme sahiptir. <code>anyhow<\/code> veya <code>thiserror<\/code> gibi k\u00fct\u00fcphanelerle Rust&#8217;\u0131n hata y\u00f6netimi yeteneklerini daha da geli\u015ftirebiliriz. Ayr\u0131ca, <code>tracing<\/code> veya <code>log<\/code> k\u00fct\u00fcphaneleriyle detayl\u0131 loglar tutarak rapor olu\u015fturma s\u00fcrecindeki potansiyel sorunlar\u0131 izleyebiliriz. Ba\u015far\u0131s\u0131z PDF d\u00f6n\u00fc\u015f\u00fcmleri, eksik veriler veya \u015fablon i\u015fleme hatalar\u0131 gibi durumlar i\u00e7in uyar\u0131 mekanizmalar\u0131 kurmak, sistemin g\u00fcvenilirli\u011fini art\u0131r\u0131r.<\/p>\n<h4>5. G\u00fcvenlik \u0130pu\u00e7lar\u0131<\/h4>\n<ul>\n<li><strong>Veri Do\u011frulama:<\/strong> \u015eablonlara aktar\u0131lan t\u00fcm verilerin g\u00fcvenilir kaynaklardan geldi\u011finden ve do\u011fru formatta oldu\u011fundan emin olun. SQL enjeksiyonu veya XSS (Cross-Site Scripting) gibi zafiyetleri \u00f6nlemek i\u00e7in girdi do\u011frulama (input validation) ve temizleme (sanitization) i\u015flemleri uygulay\u0131n. Tera&#8217;n\u0131n otomatik ka\u00e7\u0131\u015f\u0131 (autoescaping) genellikle XSS&#8217;i \u00f6nler, ancak yine de dikkatli olmak \u00f6nemlidir.<\/li>\n<li><strong>Eri\u015fim Kontrol\u00fc:<\/strong> Rapor olu\u015fturma API&#8217;sine yetkisiz eri\u015fimi engellemek i\u00e7in kimlik do\u011frulama (authentication) ve yetkilendirme (authorization) mekanizmalar\u0131 uygulay\u0131n (\u00f6rne\u011fin, JWT tabanl\u0131 tokenlar).<\/li>\n<li><strong>Headless Taray\u0131c\u0131 G\u00fcvenli\u011fi:<\/strong> <code>chromiumoxide<\/code> gibi k\u00fct\u00fcphanelerle \u00e7al\u0131\u015f\u0131rken, Headless Chrome&#8217;u en az ayr\u0131cal\u0131k ilkesiyle \u00e7al\u0131\u015ft\u0131rmak ve g\u00fcvenlik yamalar\u0131n\u0131 d\u00fczenli olarak uygulamak \u00f6nemlidir.<\/li>\n<\/ul>\n<p>Bu ileri d\u00fczey ipu\u00e7lar\u0131 ve entegrasyon senaryolar\u0131, Rust ile geli\u015ftirdi\u011finiz raporlama sistemini basit bir betikten, kurumsal d\u00fczeyde \u00f6l\u00e7eklenebilir, g\u00fcvenilir ve esnek bir \u00e7\u00f6z\u00fcme d\u00f6n\u00fc\u015ft\u00fcrmenize yard\u0131mc\u0131 olacakt\u0131r. Rust&#8217;\u0131n performans\u0131 ve g\u00fcvenlik \u00f6zellikleri, bu karma\u015f\u0131k entegrasyonlar\u0131 bile g\u00fcvenle y\u00f6netmenizi sa\u011flar.<\/p>\n<h3>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<p>Bu makalede, Rust programlama dilinin g\u00fcc\u00fcn\u00fc, HTML \u015fablonlar\u0131n\u0131n esnekli\u011fiyle birle\u015ftirerek \u00f6\u011frenci raporlar\u0131n\u0131 dinamik olarak nas\u0131l olu\u015fturup PDF format\u0131nda d\u0131\u015fa aktarabilece\u011fimizi detayl\u0131 bir \u015fekilde inceledik. Rust&#8217;\u0131n y\u00fcksek performans\u0131, bellek g\u00fcvenli\u011fi garantileri ve e\u015fzamanl\u0131l\u0131k yetenekleri sayesinde, b\u00fcy\u00fck \u00f6l\u00e7ekli raporlama ihtiya\u00e7lar\u0131 i\u00e7in g\u00fcvenilir ve verimli bir \u00e7\u00f6z\u00fcm geli\u015ftirebilece\u011fimizi g\u00f6rd\u00fck. Tera gibi \u015fablon motorlar\u0131, veri modellerimizi g\u00f6rsel olarak \u00e7ekici HTML raporlar\u0131na d\u00f6n\u00fc\u015ft\u00fcrmemizi sa\u011flarken, <code>chromiumoxide<\/code> gibi k\u00fct\u00fcphaneler, bu HTML&#8217;i en do\u011fru \u015fekilde PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcrme imkan\u0131 sunuyor. Bu yakla\u015f\u0131m, manuel raporlama s\u00fcre\u00e7lerinin getirdi\u011fi zaman kayb\u0131n\u0131 ve hata riskini ortadan kald\u0131rarak e\u011fitim kurumlar\u0131 i\u00e7in \u00f6nemli bir verimlilik art\u0131\u015f\u0131 sa\u011fl\u0131yor. Gelecekte, bu t\u00fcr sistemler daha da geli\u015ferek yapay zeka destekli analizler veya interaktif raporlama \u00f6zellikleri ile zenginle\u015ftirilebilir.<\/p>\n<h4>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h4>\n<ol>\n<li>\n        <strong>Neden Rust, Python veya Node.js gibi daha yayg\u0131n diller yerine tercih edilmeli?<\/strong><\/p>\n<p>Rust, \u00f6zellikle y\u00fcksek performans, bellek g\u00fcvenli\u011fi ve e\u015fzamanl\u0131l\u0131k gerektiren sistemler i\u00e7in idealdir. Python veya Node.js gibi dillerin geli\u015ftirme h\u0131z\u0131 avantaj\u0131 olsa da, b\u00fcy\u00fck \u00f6l\u00e7ekli rapor \u00fcretiminde Rust&#8217;\u0131n sa\u011flad\u0131\u011f\u0131 h\u0131z ve kaynak verimlili\u011fi kritik bir fark yaratabilir. Ayr\u0131ca, Rust&#8217;\u0131n g\u00fc\u00e7l\u00fc t\u00fcr sistemi, derleme zaman\u0131nda bir\u00e7ok hatay\u0131 yakalayarak daha g\u00fcvenilir kod yaz\u0131lmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<\/li>\n<li>\n        <strong>PDF d\u00f6n\u00fc\u015f\u00fcm\u00fc i\u00e7in <code>chromiumoxide<\/code> yerine ba\u015fka hangi ara\u00e7lar kullan\u0131labilir?<\/strong><\/p>\n<p><code>chromiumoxide<\/code>, Headless Chrome\/Chromium kullanarak en do\u011fru HTML&#8217;den PDF&#8217;e d\u00f6n\u00fc\u015f\u00fcm\u00fc sa\u011flar. Ancak, daha hafif veya farkl\u0131 gereksinimleriniz varsa <code>wkhtmltopdf<\/code> gibi komut sat\u0131r\u0131 ara\u00e7lar\u0131n\u0131 Rust&#8217;tan \u00e7a\u011f\u0131rabilirsiniz. Bu ara\u00e7lar genellikle bir sistemde kurulu olmay\u0131 gerektirir. Rust ekosisteminde do\u011frudan PDF olu\u015fturma k\u00fct\u00fcphaneleri (\u00f6rne\u011fin <code>printpdf<\/code>) de mevcuttur, ancak bunlar genellikle HTML\/CSS deste\u011fi sunmaz ve PDF i\u00e7eri\u011fini programatik olarak olu\u015fturman\u0131z\u0131 gerektirir.<\/p>\n<\/li>\n<li>\n        <strong>Raporlarda grafik veya g\u00f6rselle\u015ftirmeler kullanabilir miyim?<\/strong><\/p>\n<p>Evet, HTML \u015fablonlar\u0131n\u0131zda grafik k\u00fct\u00fcphaneleri (\u00f6rne\u011fin Chart.js, D3.js) kullanarak g\u00f6rselle\u015ftirmeler olu\u015fturabilirsiniz. Ancak, <code>chromiumoxide<\/code> gibi bir Headless taray\u0131c\u0131 kullan\u0131yorsan\u0131z, JavaScript&#8217;in PDF&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclmeden \u00f6nce \u00e7al\u0131\u015f\u0131p grafiklerin HTML&#8217;e \u00e7izildi\u011finden emin olman\u0131z gerekir. Bu, genellikle JavaScript&#8217;in DOM&#8217;u manip\u00fcle edip grafiklerin SVG veya Canvas olarak olu\u015fturulmas\u0131yla m\u00fcmk\u00fcn olur. Bu grafikler daha sonra PDF&#8217;e statik bir g\u00f6r\u00fcnt\u00fc olarak dahil edilir.<\/p>\n<\/li>\n<li>\n        <strong>Olu\u015fturulan raporlar\u0131 nas\u0131l da\u011f\u0131tabilirim veya depolayabilirim?<\/strong><\/p>\n<p>Olu\u015fturulan PDF dosyalar\u0131n\u0131 yerel bir dosya sistemine kaydedebilece\u011finiz gibi, bulut depolama hizmetlerine (\u00f6rne\u011fin Amazon S3, Google Cloud Storage) y\u00fckleyebilirsiniz. Raporlar\u0131 kullan\u0131c\u0131lara e-posta ile g\u00f6ndermek veya bir web aray\u00fcz\u00fc \u00fczerinden indirme ba\u011flant\u0131s\u0131 sunmak i\u00e7in de Rust&#8217;\u0131n \u00e7e\u015fitli k\u00fct\u00fcphanelerinden faydalanabilirsiniz. \u00d6rne\u011fin, bir web sunucusu (Actix-web) \u00fczerinden PDF&#8217;i do\u011frudan HTTP yan\u0131t\u0131 olarak d\u00f6nebilirsiniz.<\/p>\n<\/li>\n<li>\n        <strong>\u015eablon motoru olarak neden Tera tercih edildi? Ba\u015fka se\u00e7enekler var m\u0131?<\/strong><\/p>\n<p>Tera, Rust i\u00e7in pop\u00fcler, g\u00fc\u00e7l\u00fc ve aktif olarak geli\u015ftirilen bir \u015fablon motorudur. Django ve Jinja2&#8217;ye benzer s\u00f6zdizimi sayesinde web geli\u015ftiricileri i\u00e7in \u00f6\u011frenmesi kolayd\u0131r. Ba\u015fka bir pop\u00fcler se\u00e7enek ise <code>Handlebars<\/code>&#8216;t\u0131r. Se\u00e7im, projenizin \u00f6zel gereksinimlerine ve geli\u015ftiricinin tercihlerine ba\u011fl\u0131d\u0131r. Her iki motor da benzer i\u015flevsellikler sunar.<\/p>\n<\/li>\n<\/ol>\n<p>#Rust #WebGeli\u015ftirme #PDFExport #HTMLTemplates #SistemProgramlama<\/p>\n<div class=\"github-example-link\"><strong>\u00d6rnek kod:<\/strong> <a href=\"https:\/\/github.com\/fatihsoysalcom\/rust-student-report-pdf-generator\" target=\"_blank\" rel=\"noopener noreferrer\">github.com\/fatihsoysalcom\/rust-student-report-pdf-generator<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"E\u011fitim kurumlar\u0131nda, \u00f6\u011frenci raporlar\u0131 olu\u015fturmak genellikle zaman al\u0131c\u0131 ve hataya a\u00e7\u0131k bir s\u00fcre\u00e7tir.","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-43219","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma\" \/>\n<meta property=\"og:description\" content=\"E\u011fitim kurumlar\u0131nda, \u00f6\u011frenci raporlar\u0131 olu\u015fturmak genellikle zaman al\u0131c\u0131 ve hataya a\u00e7\u0131k bir s\u00fcre\u00e7tir.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-10T06:15:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-10T06:16:44+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"28 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma\",\"datePublished\":\"2026-07-10T06:15:38+00:00\",\"dateModified\":\"2026-07-10T06:16:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\"},\"wordCount\":4391,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\",\"name\":\"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-07-10T06:15:38+00:00\",\"dateModified\":\"2026-07-10T06:16:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/","og_locale":"tr_TR","og_type":"article","og_title":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma","og_description":"E\u011fitim kurumlar\u0131nda, \u00f6\u011frenci raporlar\u0131 olu\u015fturmak genellikle zaman al\u0131c\u0131 ve hataya a\u00e7\u0131k bir s\u00fcre\u00e7tir.","og_url":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-07-10T06:15:38+00:00","article_modified_time":"2026-07-10T06:16:44+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"28 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma","datePublished":"2026-07-10T06:15:38+00:00","dateModified":"2026-07-10T06:16:44+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/"},"wordCount":4391,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/","url":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/","name":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-07-10T06:15:38+00:00","dateModified":"2026-07-10T06:16:44+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/rust-ile-ogrenci-raporlari-nasil-olusturulur-html-sablonlari-ve-pdf-disa-aktarma\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Rust ile \u00d6\u011frenci Raporlar\u0131 Nas\u0131l Olu\u015fturulur: HTML \u015eablonlar\u0131 ve PDF D\u0131\u015fa Aktarma"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/43219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=43219"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/43219\/revisions"}],"predecessor-version":[{"id":43220,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/43219\/revisions\/43220"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=43219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=43219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=43219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}