# Rapor ve dışa aktarma

Kullanıcılar listeleri çoğu zaman **Excel'e almak** ya da **yazdırmak / PDF yapmak** ister. Devoplus One bunları
ek kütüphane gerektirmeden verir:

| İstek | Karşılığı |
|---|---|
| "Excel'e aktarabilelim" | XLSX (`toXlsx`); sayılar ve tarihler Excel'de hesaplanabilir kalır |
| "CSV olarak alalım" | CSV (`toCsv`); Türkçe karakterler bozulmaz |
| "PDF / çıktı alalım" | Yazdırma sayfası (`renderPrintableReport`) + tarayıcının "PDF olarak kaydet"i |
| "Grafikle görelim" | Hazır grafik bileşeni (`one-chart`, arayüz bileşenleri) |

## En kısa yol: veri modeli varsa hazır

[Veri modeli](/docs/data-model.md) kullanan uygulamada her kayıt türünün dışa aktarma uçları zaten vardır ve liste
süzgeçlerini aynen kabul eder:

- `GET /api/<varlık>/export.xlsx?durum=acik`
- `GET /api/<varlık>/export.csv?...`
- `GET /api/<varlık>/report.html?...` (yazdırma sayfası; para alanlarının toplamı en altta)
- `_lang=en` İngilizce başlık ve biçim verir; varsayılan Türkçedir.

## Kendi raporunuz

```ts
import { exportResponse, renderPrintableReport, reportResponse, toCsv, toXlsx, type ExportColumn } from '@devoplus/one-sdk'

const columns: ExportColumn[] = [
  { key: 'magaza', title: { tr: 'Mağaza', en: 'Store' } },
  { key: 'ciro', title: { tr: 'Ciro', en: 'Revenue' }, type: 'money' },
  { key: 'tarih', title: { tr: 'Tarih', en: 'Date' }, type: 'date' },
]
// Excel:
return exportResponse(toXlsx(rows, columns, { sheetName: 'Ekim' }), { fileName: 'Mağaza cirosu Ekim', format: 'xlsx' })
// Yazdırma sayfası:
return reportResponse(renderPrintableReport({ title: 'Mağaza cirosu', columns, rows, totals: ['ciro'] }))
```

Sütun türleri: `text` (varsayılan), `number`, `money` (`"1234.50"` ya da sayı), `date` (`YYYY-AA-GG`), `datetime`
(ISO), `boolean`. Seçim kodlarını görünen adla yazmak için `labels: { acik: { tr: 'Açık', en: 'Open' } }`.

## Arayüzde indirme ve yazdırma

Uygulama Portal'ın içindeki bir çerçevede çalışır; çerçevede doğrudan dosya indirme kapalıdır. Dosya **belirteçli**
istekle alınır ve Portal'a verilir:

```js
const res = await one.fetch('/api/talepler/export.xlsx?durum=acik')
if (!res.ok) { /* hata gövdesindeki detail'i kullanıcıya gösterin */ }
const name = decodeURIComponent((/filename\*=UTF-8''([^;]+)/.exec(res.headers.get('content-disposition') ?? '') ?? [])[1] ?? 'rapor.xlsx')
await one.download({ name, mime: res.headers.get('content-type'), data: await res.arrayBuffer() })
```

Yazdırma için sayfa gizli bir çerçevede açılır ve tarayıcının yazdırma penceresi çağrılır; kullanıcı orada
"PDF olarak kaydet"i seçer:

```js
const html = await (await one.fetch('/api/talepler/report.html?durum=acik')).text()
const frame = document.createElement('iframe')
frame.style.cssText = 'position:absolute;width:0;height:0;border:0'
frame.srcdoc = html
frame.onload = () => { frame.contentWindow.print(); setTimeout(() => frame.remove(), 60000) }
document.body.appendChild(frame)
```

Bu kodlar uygulamanın kendi betik dosyasında durur (satır içi betik platformda kapalıdır).

## Sınırlar: kullanıcıya baştan söyleyin

- **PDF dosyası sunucuda üretilmez.** PDF, yazdırma penceresindeki "PDF olarak kaydet" ile alınır.
- Bir dosyada en çok 50.000 satır ve 100 sütun; indirme en çok 25 MB. Veri modelinin hazır uçlarında dışa aktarma
  varsayılan en çok 10.000, yazdırma sayfası 2.000 kayıttır. Daha fazlası için kullanıcıdan süzgeci daraltmasını isteyin.
- CSV Türkçe ayarda `;` ile ayrılır ve sayılar `1.234,50` yazılır (Türkçe Excel böyle açar); başka bir programa
  verilecekse `toCsv(..., { lang: 'en', delimiter: ',' })`.
- Excel'de tarih-saatler İstanbul saatiyle yazılır (`timeZone` ile değişir).
- Excel bir hücrede en çok 32.767 karakter tutar; daha uzun metin kırpılır.
