💡 Tam çalışan örnek GitHub’da mevcuttur:
extract-annotations-from-pdf-using-groupdocs-parser-dotnet
Giriş
Bir PDF, incelemeden geçmiş olduğunda genellikle yalnızca görünen metninden daha fazlasını taşır – yapışkan notlar, vurgulanmış açıklamalar ve inceleyenler tarafından bırakılan satır içi yorumlar. Her sayfayı kaydırarak bunları bulmak, bir belge birkaç tur geri bildirimden geçmişse ölçeklenemez. GroupDocs.Parser, bir belgenin gömülü açıklamalarını programlı olarak okuyan bir .NET kütüphanesidir; dağınık inceleme yorumlarını, kodunuzun işleyebileceği yapılandırılmış verilere dönüştürür. Bu öğreticide, bir PDF’den tüm açıklamaları nasıl çıkaracağınızı, sayfa sayfa nasıl parçalayacağınızı, belge metniyle birlikte nasıl alacağınızı ve sonuçları CSV ya da JSON olarak dışa aktaracağınızı göstereceğiz.
Bu sorunu, bir dokümantasyon ekibi için inceleme izleyicisi oluştururken yaşadım: 40 sayfalık bir sürüm notu üç inceleyiciden geçmişti ve dosyayı manuel olarak açıp her yorumu bulmak, işaretledikleri sorunları düzeltmekten daha uzun sürüyordu. Açıklamaları birkaç satır kodla çıkarmak, işi iki dakikaya indirdi.
Aşağıdaki bölümlerde şunları öğreneceksiniz:
- Tek bir geçişte bir PDF’den tüm açıklamaları çıkarın.
- Her açıklamayı ait olduğu sayfa ile etiketleyin.
- Belge metni ve açıklama metnini tek bir okuma içinde birleştirin.
- Sonuçları CSV ya da JSON olarak serileştirerek sonraki araçlara aktarın.
PDF Açıklamalarını Çıkarma Neden Önemlidir
PDF açıklamalarını programlı olarak okumak şu durumlarda faydalıdır:
- İnceleme iş akışları: PDF görüntüleyicide dosyayı açmadan her inceleme yorumunu toplayın.
- İş birliği: Vurgulanan ya da not alınmış bölümleri doğrudan kendi araçlarınız içinde gösterin.
- Denetim: Bir belge zaman içinde düzleştirildikten ya da sonlandırıldıktan sonra bile üzerindeki işaretlemelerin kaydını tutun.
GroupDocs.Parser, PDF belgeleri için yerel açıklama çıkarımını sürüm 26.7’de GetAnnotations yöntemiyle ekledi; ayrıca TextOptions üzerindeki yeni IncludeAnnotations seçeneği, açıklama metnini normal metin okumasına dahil etmeyi sağlıyor.
Önkoşullar
- .NET 6.0 veya üzeri
- GroupDocs.Parser for .NET 26.7+ (geçici lisans)
- Mevcut açıklamaları olan bir PDF dosyası (ör.
document-with-annotations.pdf)
NuGet üzerinden kurun:
dotnet add package GroupDocs.Parser
Bir PDF belgesinden açıklamaları nasıl çıkarırım?
Cevap: Dosyayı Parser ile yükleyin, ardından tüm belge için GetAnnotations() ya da tek bir sayfa için GetAnnotations(pageIndex) çağırın. Her sonuç, Value özelliği yorum metnini tutan AnnotationItem nesnelerinin bir koleksiyonudur. Açıklamaları belge içeriğiyle aynı satırda görmek isterseniz, TextOptions üzerindeki IncludeAnnotations özelliğini ayarlayın ve GetText çağırın.
Tüm Belge Çıkarma
Aşağıdaki kod parçacığı, dosyadan tüm açıklamaları tek bir çağrıyla çeker; bu, bir belgenin herhangi bir açık yorumu olup olmadığını kontrol etmenin en hızlı yoludur.
// Extract every annotation from the whole document
var result = new List<string>();
using (var parser = new Parser(path))
{
IEnumerable<AnnotationItem> annotations = parser.GetAnnotations();
if (annotations == null)
{
return result; // format doesn't support annotations
}
foreach (var item in annotations)
{
result.Add(item.Value); // annotation text
}
}
return result;
Temel noktalar:
GetAnnotations()belge için açıklama çıkarımı desteklenmiyorsanulldöner; belge hiç açıklama içermiyorsa boş bir koleksiyon döner.- Her
AnnotationItemmetniniValueözelliği aracılığıyla sunar – SDK şu anda yalnızca bu veri noktasını raporlar. - Burada sayfa ataması bulunmaz; ihtiyacınız varsa aşağıdaki sayfa‑bazlı aşırı yüklemeyi kullanın.
Sayfa‑Bazlı Çıkarma
Yorumun konumu önemliyse, belgenin sayfaları üzerinde döngü kurun ve her biri için GetAnnotations(pageIndex) çağırın.
// Tag each annotation with its zero-based page index
var result = new List<AnnotationRecord>();
using (var parser = new Parser(path))
{
if (!parser.Features.Annotations)
{
return result;
}
var info = parser.GetDocumentInfo();
if (info == null || info.PageCount == 0)
{
return result;
}
for (int pageIndex = 0; pageIndex < info.PageCount; pageIndex++)
{
IEnumerable<AnnotationItem> pageAnnotations = parser.GetAnnotations(pageIndex);
if (pageAnnotations == null)
{
continue;
}
foreach (var item in pageAnnotations)
{
result.Add(new AnnotationRecord { PageIndex = pageIndex, Value = item.Value });
}
}
}
return result;
Temel noktalar:
GetDocumentInfo().PageCountdöngüyü yönlendirir; ayrı bir “açıklama sayfa sayısı” yoktur.GetAnnotations(pageIndex)sıfır‑tabanlı bir indeks kullanır; API’deki diğer sayfa‑seviyesi yöntemlerle aynı uyumluluğu sağlar.- Oluşan
AnnotationRecordlistesi, CSV ya da JSON dışa aktarımı için tam olarak gereken şekildedir.
Açıklamalarla Birlikte Metin Çıkarma
Belgeyi iki kez dolaşmak yerine, açıklama metnini doğrudan normal metin çıkarım çıktısına katlayabilirsiniz.
// Read document text with annotation text included
using (var parser = new Parser(path))
{
var options = new TextOptions
{
IncludeAnnotations = true
};
using (TextReader reader = parser.GetText(options))
{
return reader?.ReadToEnd() ?? string.Empty;
}
}
Temel noktalar:
IncludeAnnotations,TextOptionsüzerindeki bir özelliktir; bu, düz metin çıkarımı için zaten kullandığınızGetTextçağrısıyla aynı şekilde çalışır.- Tek bir transcript‑stil çıktısı istediğinizde, ayrı bir yorum listesine ihtiyaç duymadığınızda faydalıdır.
- Sadece bir sayfa için ihtiyacınız varsa
GetText(pageIndex, options)ile birleştirebilirsiniz.
Önce Açıklama Desteğini Kontrol Etme
Her format açıklamaları desteklemez; bu yüzden GetAnnotations etrafında mantık kurmadan önce kontrol etmek iyidir.
// Returns true if the loaded document format supports annotation extraction
using (var parser = new Parser(path))
{
return parser.Features.Annotations;
}
Temel noktalar:
Features.Annotations,Parserörneği üzerinde basit bir boolean bayrağıdır.- Önceden kontrol etmek, niyetinizi açıkça ortaya koyar;
GetAnnotationszatennulldöndürerek nazikçe başarısız olur.
Açıklamaları CSV’ye Dışa Aktarma
CSV dışa aktarımı, inceleyenlerin yorum listesini doğrudan Excel’de açmasını sağlar. Aşağıdaki yöntem, önceki adımda oluşturulan sayfa‑etiketli kayıtları iki sütunlu (page,value) bir dosyaya yazar.
var sb = new StringBuilder();
sb.AppendLine("page,value");
foreach (var record in records)
{
sb.AppendLine($"{record.PageIndex},{CsvEscape(record.Value)}");
}
File.WriteAllText(outputPath, sb.ToString());
Temel noktalar:
CsvEscape, virgül, çift tırnak ya da satır sonu içeren alanları güvenli bir şekilde tırnak içine alır.- Oluşan dosya doğrudan Excel’de açılır ya da bir biletleme aracına yönlendirilebilir.
Yardımcı: CsvEscape
if (string.IsNullOrEmpty(s)) return string.Empty;
if (s.Contains(",") || s.Contains("\"") || s.Contains("\n"))
{
return "\"" + s.Replace("\"", "\"\"") + "\"";
}
return s;
Açıklamaları JSON’a Dışa Aktarma
Yorumları programlı olarak tüketen akışlar için, JSON dizisi genellikle düz CSV’den daha uygundur.
var sb = new StringBuilder();
sb.AppendLine("[");
for (int i = 0; i < records.Count; i++)
{
var comma = i < records.Count - 1 ? "," : string.Empty;
sb.AppendLine($" {{ \"page\": {records[i].PageIndex}, \"value\": \"{Escape(records[i].Value)}\" }}{comma}");
}
sb.AppendLine("]");
File.WriteAllText(outputPath, sb.ToString());
Temel noktalar:
- Çıktı,
{ page, value }nesnelerinden oluşan düz bir dizi – herhangi bir sonraki hizmetin kolayca serileştirmesini sağlar. Escape, bir serileştirme kütüphanesi eklemeden JSON geçerliliğini korur.
Yardımcı: Escape
return s?.Replace("\\", "\\\\").Replace("\"", "\\\"") ?? string.Empty;
Yöntemleri Karşılaştırma: Ne Zaman Hangi Yöntemi Kullanmalı
| Yöntem | En İyi Kullanım Durumu | Temel Avantajlar | Kısıtlamalar |
|---|---|---|---|
| Tüm‑Belge Çıkarma | “Herhangi bir yorum var mı?” hızlı kontrolü | Tek çağrı, en basit kod | Sayfa ataması yok |
| Sayfa‑Bazlı Çıkarma | Geri bildirimi doğru bölüme yönlendirme | Sayfa‑etiketli sonuçlar, dışa aktarmaya hazır | Sayfa başına ekstra çağrı |
| Metin + Açıklamalar Birleşik | Tek okunabilir transcript | Belgeye ikinci geçiş yok | Yorumlar metinden ayrı değildir |
| CSV Dışa Aktarma | Tablo‑tabanlı inceleme takibi | Excel’de kolay açılır, insan‑okunur | Düz yapı ile sınırlı |
| JSON Dışa Aktarma | Otomatik akışlar, biletleme sistemleri | Yapılandırılmış, makine‑okunur | Biraz daha büyük yük |
İlk olarak, bir dosyanın yorum içerip içermediğini doğrulamak için tüm‑belge çıkarımını kullanın; ardından belirli bir bölüme geri bildirimi yönlendirmeniz gerektiğinde sayfa‑bazlı çıkarıma geçin.
En İyi Uygulamalar ve İpuçları
Parserı hemen serbest bırakın: yerel kaynakları temizlemek içinusingbloğu içinde tutun.nullile boş koleksiyonu ayırt edin:GetAnnotationsnulldöndürürse format desteklenmiyordur; boş koleksiyon ise belge yorum içermiyordur.- Toplu işlerde
Features.Annotationskontrol edin: döngünüzün içindenullkontrolüne bel bağlamadan, desteklenmeyen dosyaları erken atlayın. - Sayfa‑etiketli listeyi yeniden kullanın:
ExtractAnnotationsByPageile bir kez oluşturun ve CSV ile JSON dışa aktarıcılarını aynı veriden besleyin; böylece iki çıktı asla birbirinden farklılaşmaz. - Güvenlik: Açıklama metni serbest biçimli inceleme girdisidir – UI ya da raporda göstermeden önce diğer güvensiz stringler gibi işleyin.
Sonuç
GroupDocs.Parser, PDF’den inceleme yorumlarını elle aramak yerine doğrudan, programlı bir şekilde çekmenizi sağlar. Açıklamaları tüm belge için çıkararak, sayfa ile etiketleyerek ya da normal metin akışına katlayarak, belge pipeline’ınıza girdiği anda geri bildirimi ortaya çıkaran inceleme iş akışları oluşturabilirsiniz. Sonuçları CSV ya da JSON olarak dışa aktarın ve ekibinizin zaten kullandığı araçlara doğrudan bağlayın.
Sonraki adımlar:
- Tam yöntem imzası ve aşırı yüklemeleri için GetAnnotations API referansına göz atın.
- Açıklamalarla birlikte PDF belgelerinden metin çıkarmayı öğrenmek için PDF belgelerinden metin çıkarma sayfasını inceleyin.
- Toplu‑işleme senaryoları için GitHub’da ek örnek projelere bakın (Örnekler Deposu).