如何用iTextSharp导出含外部API数据的DataTables视图为PDF?
Got it, let's tackle your problem step by step. Since you're pulling data directly from an external API with jQuery/DataTables instead of using server-side models, we have two solid approaches to export your view to PDF with iTextSharp—each with its own pros and cons depending on your needs.
Approach 1: Export from Frontend-Generated HTML
This method captures the fully rendered HTML of your view (including the dynamic DataTables data) and sends it to your backend for conversion to PDF. It’s great if you want to reuse your existing frontend styling and layout.
Step 1: Frontend Code (Index.cshtml)
Add a click handler to your export button that grabs the target HTML and sends it to your controller:
$("#exportPdfBtn").click(function() { // Capture the entire view or just the table container (adjust selector as needed) var exportHtml = $("#tableContainer").html(); // Send HTML to backend via AJAX $.ajax({ url: "/Report/ExportPdfFromHtml", type: "POST", data: { htmlContent: exportHtml }, success: function(pdfData) { // Trigger download of the PDF const blob = new Blob([pdfData], { type: "application/pdf" }); const downloadUrl = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = downloadUrl; link.download = "report.pdf"; document.body.appendChild(link); link.click(); window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }, error: function(xhr) { console.error("PDF export failed:", xhr.responseText); } }); });
Step 2: Backend Code (ReportController.cs)
Use iTextSharp’s XMLWorkerHelper to parse the incoming HTML and generate a PDF:
using iTextSharp.text; using iTextSharp.text.pdf; using iTextSharp.tool.xml; using System.IO; using System.Web.Mvc; public class ReportController : Controller { public ActionResult Index() { return View(); } [HttpPost] public ActionResult ExportPdfFromHtml(string htmlContent) { // Initialize PDF document and memory stream var document = new Document(PageSize.A4, 20, 20, 20, 20); var memoryStream = new MemoryStream(); var writer = PdfWriter.GetInstance(document, memoryStream); document.Open(); // Parse HTML content into the PDF using (var stringReader = new StringReader(htmlContent)) { XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, stringReader); } document.Close(); // Return PDF as downloadable file return File(memoryStream.ToArray(), "application/pdf", "report.pdf"); } }
Approach 2: Re-fetch Data in Backend to Build PDF
If you want more control over the PDF’s formatting (and avoid potential CSS compatibility issues with iTextSharp), have your backend re-call the external API to fetch data, then build the PDF manually.
Step 1: Frontend Code (Index.cshtml)
Pass your search parameters to the backend so it can retrieve the correct data:
$("#exportPdfBtn").click(function() { // Collect your search filters (adjust based on your form fields) const searchParams = { keyword: $("#searchKeyword").val(), startDate: $("#startDate").val() }; // Redirect to the export action with parameters window.location.href = "/Report/ExportPdfFromApi?" + $.param(searchParams); });
Step 2: Backend Code (ReportController.cs)
Call the external API, parse the response, and build the PDF from scratch:
using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; using System.Net.Http; using System.Threading.Tasks; using System.Web.Mvc; using Newtonsoft.Json; public class ReportController : Controller { public ActionResult Index() { return View(); } public async Task<ActionResult> ExportPdfFromApi(string keyword, string startDate) { // Call your external API to get data using (var httpClient = new HttpClient()) { var apiUrl = $"https://yourexternalapiendpoint.com/data?keyword={keyword}&startDate={startDate}"; var response = await httpClient.GetAsync(apiUrl); response.EnsureSuccessStatusCode(); var jsonResponse = await response.Content.ReadAsStringAsync(); // Parse JSON to dynamic object (no model needed) dynamic dataItems = JsonConvert.DeserializeObject(jsonResponse); // Initialize PDF document var document = new Document(PageSize.A4, 20, 20, 20, 20); var memoryStream = new MemoryStream(); var writer = PdfWriter.GetInstance(document, memoryStream); document.Open(); // Add report title var title = new Paragraph("Report Data", FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 16)); title.Alignment = Element.ALIGN_CENTER; document.Add(title); document.Add(Chunk.NEWLINE); // Create table (adjust column count to match your data) var pdfTable = new PdfPTable(4); pdfTable.WidthPercentage = 100; // Add table headers var headers = new[] { "ID", "Name", "Value", "Date" }; foreach (var header in headers) { var cell = new PdfPCell(new Phrase(header, FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 12))); cell.BackgroundColor = BaseColor.LIGHT_GRAY; cell.HorizontalAlignment = Element.ALIGN_CENTER; pdfTable.AddCell(cell); } // Add data rows foreach (var item in dataItems) { pdfTable.AddCell(new Phrase(item.Id.ToString())); pdfTable.AddCell(new Phrase(item.Name)); pdfTable.AddCell(new Phrase(item.Value.ToString())); pdfTable.AddCell(new Phrase(item.Date)); } document.Add(pdfTable); document.Close(); return File(memoryStream.ToArray(), "application/pdf", "report.pdf"); } } }
Key Notes
- Package Dependencies: For Approach 1, install
iTextSharpandiTextSharp.xmlworkervia NuGet. For Approach 2, addNewtonsoft.Jsonas well. - CSS Compatibility: iTextSharp’s XMLWorker has limited CSS support—if you use Approach 1, simplify your frontend styles to avoid rendering issues.
- Async Handling: Always use
async/awaitwhen calling external APIs in the backend to prevent blocking requests.
内容的提问来源于stack exchange,提问作者Aya Abdelaziz

