2016-09-26 18 views
5

Giải pháp cho C# bạn có thể tìm thấy trong phần Chỉnh sửa của Câu hỏi. Đặc biệt Cảm ơn Bruno LowagieC# - itextSharp tổng phụ trên mỗi trang

Tôi đang cố tạo hóa đơn qua iTextSharp trong C#. Nó hoạt động rất tốt nhưng im gettin vấn đề trong khi tôi cố gắng in subtotal trên mỗi trang.

Đây là một phần của im mã sử dụng để tạo ra bảng cho các sản phẩm:

PdfPTable table = new PdfPTable(5); 
     table.WidthPercentage = 100; 
     float[] widths = new float[] { 10f, 30f, 120f, 30f, 30f }; 
     table.SetWidths(widths); 
     table.SkipLastFooter = true; 
     table.SpacingAfter = 10;      

     //Cells to Write Header & Footer 
     AddCell(table, "Pos.", PdfPCell.ALIGN_RIGHT, BORDER_LTB, 0); 
     AddCell(table, "Menge", PdfPCell.ALIGN_RIGHT, BORDER_TB); 
     AddCell(table, "Text", PdfPCell.ALIGN_LEFT, BORDER_TB); 
     AddCell(table, "Einzelpreis ", PdfPCell.ALIGN_RIGHT, BORDER_TB); 
     AddCell(table, "Summe", PdfPCell.ALIGN_RIGHT, BORDER_RTB); 

     AddCell(table, "SUBTOTAL", PdfPCell.ALIGN_LEFT, BORDER_LTB, 7, 4); 
     AddCell(table, "", PdfPCell.ALIGN_LEFT, BORDER_RTB); 

     table.HeaderRows = 2; 
     table.FooterRows = 1; 

     //Cells with positions of invoice 
     for (int i = 0; i < beleg.Einzel.Count; i++) 
     { 
      AddCell(table, beleg.Einzel[i].be_lfd_nr.ToString(), PdfPCell.ALIGN_LEFT, BORDER_LTB); 
      AddCell(table, beleg.Einzel[i].be_art_menge.ToString("N", _gbVars.NFI3D), PdfPCell.ALIGN_RIGHT, BORDER_TB); 
      AddCell(table, (beleg.Einzel[i].be_art_bez.ToString() + "\n" + beleg.Einzel[i].be_pos_text.ToString()).Trim(), PdfPCell.ALIGN_LEFT, BORDER_TB); 
      AddCell(table, beleg.Einzel[i].be_summe_preis.ToString("N", _gbVars.NFI2D), PdfPCell.ALIGN_RIGHT, BORDER_TB); 
      AddCell(table, beleg.Einzel[i].be_summe_netto.ToString("N", _gbVars.NFI2D), PdfPCell.ALIGN_RIGHT, BORDER_RTB); 
     } 

     table.SplitLate = false; 
     document.Add(table); 

Border_RTB và như vậy là hằng số cho tôi Border-Styles.

Mã này tạo ra một phù thủy bảng trông như thế này:

+------------------------------------------+ 
| Pos | Menge | Text | Einzelpreis | Summe | 
+------------------------------------------+ 
| 1 | 2 | Text |  10.00 | 20.00 | 
+------------------------------------------+ 
| 2 | 1 | Text |  10.00 | 10.00 | 
+------------------------------------------+ 
| 3 | 4 | Text |  10.00 | 40.00 | 
+------------------------------------------+ 
| 4 | 2 | Text |  10.00 | 20.00 | 
+------------------------------------------+ 
|SUBTOTAL       |  | 
+------------------------------------------+ 

Bảng có thể chảy đến trang tiếp theo một i whant để viết tổng số phụ của mỗi trang ở chân. Sự kiện "OnEndPage" không giúp tôi vì sự kiện này không "biết" ở đâu trong bảng trang bị hỏng.

Ai đó có thể cho tôi biết cách tôi nhận tổng số phụ trên mỗi trang? Có giải pháp làm thế nào tôi có thể tổng hợp một cái gì đó trên một trang in nó ra trên tập tin pdf?

Xin lỗi nếu mô tả của tôi không tốt. Có vấn đề với tiếng anh của tôi. : -/

EDIT:

Đây là giải pháp. Đặc biệt Cảm ơn Bruno. Anh ấy đã chỉ cho tôi cách. Trong Phiên bản của tôi, Subtotal KHÔNG Reset trên mọi Trang. Tôi đoán đây là một sự hiểu lầm trong mô tả của tôi về vấn đề này.

Các tác phẩm Clases mới:

public class Totals 
    { 
     public double subtotal = 0; 
     public double total = 0; 
    } 


    public class SubTotalEvent : IPdfPCellEvent 
    { 
     Double price; 
     Totals totals; 
     bool printTotals = false;  //If we just whant to print out the Subtotal, this will be true. 
     bool CellWrittenOnce = false; //Bool to SUM price just once (if row flows to a second page) 

     public SubTotalEvent(Totals totals, double price) { 
      printTotals = false; 
      this.totals = totals; 
      this.price = price; 
     } 

     public SubTotalEvent(Totals totals) { 
      this.totals = totals; 
      printTotals = true; 
     } 

     public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { 
      if (printTotals) 
      { 
       PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS]; 
       ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(totals.subtotal.ToString()), position.GetLeft(0) + 2, position.GetBottom(0) + 2, 0); 
       return; 
      }  
      if (!CellWrittenOnce) { 
       totals.subtotal += price; 
       totals.total += price; 
      } 
      CellWrittenOnce = true; 
     } 
    } 

Mã để tạo ra các bảng:

PdfPTable table = new PdfPTable(5); 
     table.WidthPercentage = 100; 
     float[] widths = new float[] { 10f, 30f, 120f, 30f, 30f }; 
     table.SetWidths(widths); 
     table.SkipLastFooter = true; 
     table.SpacingAfter = 10;      

     AddCell(new PdfPCell(new Phrase("item"))); 
     AddCell(new PdfPCell(new Phrase("amount"))); 
     AddCell(new PdfPCell(new Phrase("text"))); 
     AddCell(new PdfPCell(new Phrase("price"))); 
     AddCell(new PdfPCell(new Phrase("sum"))); 

     Totals totals = new Totals(); 
     PdfPCell cel = new PdfPCell(new Phrase("Subtotal")); 
     cel.Colspan = 4; 
     table.AddCell(cel); 
     cel = new PdfPCell(); 
     cel.CellEvent = new SubTotalEvent(totals); 
     table.AddCell(cel); 


     table.HeaderRows = 2; 
     table.FooterRows = 1; 

     for (int i = 0; i < beleg.Einzel.Count; i++) 
     { 
      AddCell(new PdfPCell(new Phrase(i.toString()))); 
      AddCell(new PdfPCell(new Phrase("2"))); 
      AddCell(new PdfPCell(new Phrase("ItemText"))); 
      AddCell(new PdfPCell(new Phrase("10.00"))); 

      cell = new PdfPCell(new Phrase("20.00")); 
      cell.CellEvent = new SubTotalEvent(totals, 20.00); 
      table.AddCell(cell); 
     } 

     table.SplitLate = false; 
     document.Add(table); 
+2

Bạn cần triển khai lớp 'PdfPageEventHelper'. Việc triển khai của bạn sẽ thực thi mỗi khi trang được tạo. Xem hướng dẫn này về cách triển khai nó http://www.mazsoft.com/blog/post/2008/04/30/Code-sample-for-using-iTextSharp-PDF-library – Darren

+1

Tôi triển khai lớp 'PdfPageEventHelper'. Nhưng làm thế nào tôi có thể tìm ra trong 'void override công khai OnEndPage (PdfWriter writer, Document doc)' nơi tôi đang ở trong bảng? Bảng đã được viết vào thời điểm này. Sự kiện này được gọi tại 'document.Add (table); ' –

+0

Một số điều không rõ ràng ngay với tôi từ mô tả sự cố của bạn, vì vậy tôi không chắc chắn liệu mình có câu trả lời hay không. Các giả định sau có đúng không: 1. tài liệu hóa đơn của bạn bao gồm một bảng lớn duy nhất có thể có thể mở rộng nhiều trang. 2. Hóa đơn của bạn không phải là biểu mẫu, bạn có quyền truy cập vào tất cả thông tin khi tạo tài liệu. 3. Bạn muốn in tổng phụ bao gồm tất cả các sản phẩm trên trang hiện tại + tổng số phụ cho đến trang hiện tại trong đầu trang/chân trang của trang đó. –

Trả lời

1

Xin hãy nhìn vào ví dụ SubTotal.

Đầu tiên chúng ta tạo ra một lớp học để theo dõi các tổng phụ và tổng số:

class Totals { 
    double subtotal = 0; 
    double total = 0; 
} 

Sau đó, chúng tôi thực hiện các giao diện PdfPCellEvent rằng chúng tôi sẽ sử dụng trên cột 5:

class SubTotalEvent implements PdfPCellEvent { 

    Double price; 
    Totals totals; 

    public SubTotalEvent(Totals totals, double price) { 
     this.totals = totals; 
     this.price = price; 
    } 

    public SubTotalEvent(Totals totals) { 
     this.totals = totals; 
     price = null; 
    } 

    @Override 
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { 
     if (price == null) { 
      PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS]; 
      ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, 
        new Phrase(String.valueOf(totals.subtotal)), 
        position.getLeft() + 2, position.getBottom() + 2, 0); 
      totals.subtotal = 0; 
      return; 
     } 
     totals.subtotal += price; 
     totals.total += price; 
    } 

} 

Chúng tôi đã xác định hai hàm tạo: một cho một ô bình thường chứa một giá. Một cho ô chân trang chứa tổng phụ (trong trường hợp này chúng tôi không chuyển giá).

Đây là cách chúng ta sử dụng sự kiện này tế bào:

public void createPdf(String dest) throws IOException, DocumentException { 

    Totals totals = new Totals(); 

    Document document = new Document(); 
    PdfWriter.getInstance(document, new FileOutputStream(dest)); 
    document.open(); 
    PdfPTable table = new PdfPTable(5); 
    table.setWidths(new int[]{1, 1, 1, 3, 3}); 
    // header 
    table.addCell("Pos"); 
    table.addCell("Menge"); 
    table.addCell("Text"); 
    table.addCell("Einzerpreis"); 
    table.addCell("Summe"); 
    // footer 
    PdfPCell cell = new PdfPCell(new Phrase("Subtotal")); 
    cell.setColspan(4); 
    table.addCell(cell); 
    cell = new PdfPCell(); 
    cell.setCellEvent(new SubTotalEvent(totals)); 
    table.addCell(cell); 
    // definitions 
    table.setHeaderRows(2); 
    table.setFooterRows(1); 
    // table body 
    for(int r = 0; r < 50;){ 
     table.addCell(String.valueOf(++r)); 
     table.addCell("1"); 
     table.addCell("text"); 
     table.addCell("10.0"); 
     cell = new PdfPCell(new Phrase("10.0")); 
     cell.setCellEvent(new SubTotalEvent(totals, 10)); 
     table.addCell(cell); 
    } 
    document.add(table); 
    // extra footer 
    table = new PdfPTable(5); 
    table.setWidths(new int[]{1, 1, 1, 3, 3}); 
    cell = new PdfPCell(new Phrase("Grand total")); 
    cell.setColspan(4); 
    table.addCell(cell); 
    table.addCell(String.valueOf(totals.total)); 
    document.add(table); 
    document.close(); 
} 

Kết quả trông như thế này:

enter image description here

Trên trang đầu tiên, chúng tôi có 46 dòng cơ thể cho mỗi một mục với giá 10.Ở chân trang, chúng tôi có tổng phụ 460. Trên trang thứ hai, chúng tôi có 4 hàng nội dung cho mỗi mục có giá 10. Trong chân trang, chúng tôi có tổng số phụ là 40. Chúng tôi đã thêm một bảng phụ để bắt chước một chân trang phụ cho Tổng số: 500.

+0

Chúng tôi sắp hoàn tất! Cảm ơn bạn rất nhiều! Có một vấn đề còn lại: Nếu, ví dụ, hàng 46 sẽ có chiều cao lớn hơn và chảy qua hai trang, tổng số phụ trong ví dụ của bạn trên trang một sẽ chính xác. Nhưng trên trang hai nó sẽ là 50, không phải 40. Nhưng tôi đã cố định điều đó với một biến bool bổ sung.Đối với tất cả người đọc: Mã trên từ Bruno Lowagie là JAVA-Code. Đối với C# bạn phải dịch. Nhưng nó hoạt động rất tốt! Tuyệt vời. :-) –

Các vấn đề liên quan