질문:
3개의 다른 PDF 바이트 배열을 포함하는 코드가 있습니다. 그리고 그것들을 병합하세요. 이 코드는 잘 실행됩니다. 일부 사람들은 각 PDF가 전체 페이지(인쇄된 경우)로 처리되기 때문에 문제가 발생합니다. 비록 내용이 약 4인치에 불과하고 세로 공백이 7인치 남아 있음에도 마찬가지입니다. 그런 다음 중간 문서가 삽입되고 끝에 세로 공백이 없을 수 있습니다. 그러면 바닥글도 자체 페이지에 배치됩니다.
코드는 다음과 같습니다.
byte[] Bytes = rv.LocalReport.Render("PDF", null, out MimeType, out Encoding, out Extension, out StreamIDs, out Warnings); List<byte[]> MergeSets = // 在此代码之前填充 // 将任何其他页面附加到此主要信件 if (MergeSets.Count > 0) { MemoryStream ms = new MemoryStream(); Document document = new Document(); PdfCopy copy = new PdfCopy(document, ms); document.Open(); PdfImportedPage page; PdfReader reader = new PdfReader(Bytes); // 读取生成的正文信 int pages = reader.NumberOfPages; for (int i = 0; i < pages;) { page = copy.GetImportedPage(reader, ++i); copy.AddPage(page); } // 遍历所有正文信的页面 // 现在附加合并集 foreach (byte[] ba in MergeSets) { reader = new PdfReader(ba); pages = reader.NumberOfPages; for (int i = 0; i < pages;) { page = copy.GetImportedPage(reader, ++i); copy.AddPage(page); } // 遍历当前合并集中的所有页面 } // 遍历数据集中所有内容 document.Close(); ServerSaved = SaveGeneratedLetter(ms.GetBuffer(), DateTime.Now.Year, hl.LetterName, SaveName); } // 如果有待合并的任何内容
질문:
각 페이지를 세로로 병합할 때 잘라내기/삭제/삭제하는 방법이 있나요? 각 PDF 끝에 공백을 추가하여 하나의 매끄러운 문서로 보이도록 하시겠습니까?
업데이트:
다음은 병합하려는 샘플 .pdf 파일입니다.
제목, 본문, 바닥글
업데이트 2: 답변 사용:
아래와 같이 @mkl의 코드를 C#으로 변환했습니다.
유틸리티 클래스:
public class PdfVeryDenseMergeTool { private Rectangle PageSize; private float TopMargin; private float BottomMargin; private float Gap; private Document Document = null; private PdfWriter Writer = null; private float YPosition = 0; public PdfVeryDenseMergeTool(Rectangle size, float top, float bottom, float gap) { this.PageSize = size; this.TopMargin = top; this.BottomMargin = bottom; this.Gap = gap; } // PdfVeryDenseMergeTool public void Merge(MemoryStream outputStream, List<PdfReader> inputs) { try { this.OpenDocument(outputStream); foreach (PdfReader reader in inputs) { this.Merge(reader); } // 遍历待合并的 PDF 文件 } finally { this.CloseDocument(); } // try-catch-finally } // Merge public void OpenDocument(MemoryStream outputStream) { this.Document = new Document(PageSize, 36, 36, this.TopMargin, this.BottomMargin); this.Writer = PdfWriter.GetInstance(Document, outputStream); this.Document.Open(); this.NewPage(); } // OpenDocument public void CloseDocument() { try { this.Document.Close(); } finally { this.Document = null; this.Writer = null; this.YPosition = 0; } // try-finally } // CloseDocument public void NewPage() { this.Document.NewPage(); this.YPosition = PageSize.GetTop(this.TopMargin); } // Merge public void Merge(PdfReader reader) { PdfReaderContentParser parser = new PdfReaderContentParser(reader); for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++) { this.Merge(reader, parser, pageIndex); } // 遍历当前 PDF 的所有页面 } // Merge public void Merge(PdfReader reader, PdfReaderContentParser parser, int pageIndex) { PdfImportedPage importedPage = Writer.GetImportedPage(reader, pageIndex); PdfContentByte directContent = Writer.DirectContent; PageVerticalAnalyzer finder = parser.ProcessContent(pageIndex, new PageVerticalAnalyzer()); if (finder.VerticalFlips.Count < 2) return; Rectangle pageSizeToImport = reader.GetPageSize(pageIndex); int startFlip = finder.VerticalFlips.Count - 1; bool first = true; while (startFlip > 0) { if (!first) this.NewPage(); float freeSpace = this.YPosition - PageSize.GetBottom(BottomMargin); int endFlip = startFlip + 1; while ((endFlip > 1) && (finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip - 2] < freeSpace)) endFlip -= 2; if (endFlip < startFlip) { float height = finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip]; directContent.SaveState(); directContent.Rectangle(0, this.YPosition - height, pageSizeToImport.Width, height); directContent.Clip(); directContent.NewPath(); this.Writer.DirectContent.AddTemplate(importedPage, 0, this.YPosition - (finder.VerticalFlips[startFlip] - pageSizeToImport.Bottom)); directContent.RestoreState(); this.YPosition -= height + this.Gap; startFlip = endFlip - 1; } else if (!first) { throw new ArgumentException(string.Format("Page {0} content too large", pageIndex)); } // if first = false; } // while } // Merge } // PdfVeryDenseMergeTool
렌더링 리스너 클래스:
업데이트 3: 코드 한 줄 수정 이제 제대로 작동함 : 코드의 댓글 보기
public class PageVerticalAnalyzer : IRenderListener { public PageVerticalAnalyzer() { } public List<float> VerticalFlips = new List<float>(); public void AddVerticalUseSection(float from, float to) { if (to < from) { float temp = to; to = from; from = temp; } int i = 0; int j = 0; for (i = 0; i < VerticalFlips.Count; i++) { float flip = VerticalFlips[i]; if (flip < from) continue; for (j = i; j < VerticalFlips.Count; j++) { flip = VerticalFlips[j]; if (flip < to) continue; break; } break; } // 遍历所有垂直翻转 bool fromOutsideInterval = i % 2 == 0; bool toOutsideInterval = j % 2 == 0; while (j-- > i) VerticalFlips.RemoveAt(j); // 这是存在问题的代码行,只使用了 .Remove(j) if (toOutsideInterval) VerticalFlips.Insert(i, to); if (fromOutsideInterval) VerticalFlips.Insert(i, from); } // AddVerticalUseSection public void BeginTextBlock() { /* Do nothing */ } public void EndTextBlock() { /* Do nothing */ } public void RenderImage(ImageRenderInfo renderInfo) { Matrix ctm = renderInfo.GetImageCTM(); List<float> YCoords = new List<float>(4) { 0, 0, 0, 0 }; for (int x = 0; x < 2; x++) { for (int y = 0; y < 2; y++) { Vector corner = new Vector(x, y, 1).Cross(ctm); YCoords[2 * x + y] = corner[Vector.I2]; } } YCoords.Sort();
위 내용은 PDF를 병합할 때 공백을 제거하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!