如何用iText 7克隆PDF左侧内容并调整代码实现预期效果?
用iText 7实现PDF单栏内容克隆为双栏布局的正确姿势
嘿,你的思路方向完全没问题——用copyAsFormXObject复制原页面内容,再把副本放到新页面里实现双栏,完全可行!但你当前的代码在页面旋转、缩放矩阵和内容定位上出了点小问题,导致没达到预期效果,我来帮你修正:
问题出在哪?
看你的代码,主要有两个容易踩的坑:
- 没必要给新页面加
page.setRotation(90),这会直接打乱PDF的坐标系统,让后续的位置计算全部错位,除非你明确需要横向布局且特意处理旋转后的坐标,否则这个操作完全多余。 - 缩放比例和XObject的放置坐标不匹配,导致内容要么显示位置不对,要么缩放比例异常。
修正后的代码(附详细注释)
下面是调整后的完整代码,关键修改点我都标出来了:
public void clonePageContent(String dest) throws IOException { // 初始化源PDF和目标PDF PdfDocument sourcePdf = new PdfDocument(new PdfReader(SRC)); PdfDocument pdf = new PdfDocument(new PdfWriter(dest)); // 获取原页面和它的尺寸 PdfPage origPage = sourcePdf.getPage(1); Rectangle origSize = origPage.getPageSize(); // 把原页面内容复制成可复用的Form XObject PdfFormXObject pageCopy = origPage.copyAsFormXObject(pdf); // 定义新页面尺寸:直接把宽度设为原页面的2倍,高度保持一致,刚好容纳左右双栏 PageSize newPageSize = new PageSize(origSize.getWidth() * 2, origSize.getHeight()); PdfPage page = pdf.addNewPage(newPageSize); // 创建画布用于绘制内容 PdfCanvas canvas = new PdfCanvas(page); // -------------------------- // 处理第一个副本(左侧栏) // -------------------------- // 缩放比例:因为要放两个副本,所以把原内容缩到1/2宽(等比缩放,高度同步缩小) float scale = 0.5f; // 应用缩放矩阵,然后把副本放到页面左上角(0,0位置) canvas.concatMatrix(scale, 0, 0, scale, 0, 0); canvas.addXObject(pageCopy); // -------------------------- // 处理第二个副本(右侧栏) // -------------------------- // 重置画布矩阵,避免之前的缩放影响后续绘制 canvas.resetMatrix(); // 同样应用缩放,然后把X坐标偏移设为原页面的宽度(缩放后内容刚好落在右侧栏位置) canvas.concatMatrix(scale, 0, 0, scale, origSize.getWidth(), 0); canvas.addXObject(pageCopy); // 关闭文档,释放资源 pdf.close(); sourcePdf.close(); }
关键修改说明
- 移除不必要的页面旋转:删掉
page.setRotation(90),除非你明确需要横向展示双栏(后面会说这种情况的处理方式)。 - 调整新页面尺寸:把新页面宽度设为原页面的2倍,这样左右两个缩小后的副本刚好填满页面,不会出现内容溢出或空白过大的问题。
- 简化缩放与定位:
- 用
0.5f的固定缩放比例,确保原内容缩小一半后能适配双栏宽度。 - 第一个副本放在页面最左侧,第二个副本通过偏移原页面宽度的距离,精准落在右侧栏位置。
- 用
- 重置矩阵:每次绘制新内容前重置矩阵,避免之前的变换影响后续操作,这是很容易忽略的细节!
如果你需要横向双栏怎么办?
如果原页面是纵向(比如Letter规格:8.5×11英寸),你想把页面旋转为横向来放双栏,那可以这么调整:
// 设置新页面为横向Letter PageSize newPageSize = PageSize.LETTER.rotate(); PdfPage page = pdf.addNewPage(newPageSize); // 计算缩放比例:让原内容高度适配横向页面的高度 float scale = newPageSize.getHeight() / origSize.getHeight(); // 左侧副本 canvas.concatMatrix(scale, 0, 0, scale, 0, 0); canvas.addXObject(pageCopy); // 右侧副本 canvas.resetMatrix(); canvas.concatMatrix(scale, 0, 0, scale, origSize.getWidth() * scale, 0); canvas.addXObject(pageCopy);
这样调整后,就能得到横向布局的双栏效果了!
内容的提问来源于stack exchange,提问作者Jestino Sam
相关产品推荐
相关产品推荐

