【问题标题】:Remove the margins in the header using Apache POI in Java在 Java 中使用 Apache POI 删除页眉中的边距
【发布时间】:2022-07-25 21:41:21
【问题描述】:

我使用的是 Apache POI 4.1.2 版。当我尝试在标题中创建带有图像的文档时,在图像的 4 侧为标题分配了一些默认边距。

如何删除页眉部分的默认边距并将图像完全占据页眉部分?

XWPFDocument document = new XWPFDocument();
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(document, sectPr);
XWPFHeader header = document.createHeader(HeaderFooterType.FIRST);
XWPFParagraph paragraph = header.createParagraph();
XWPFRun run = paragraph.createRun();

//Adding the image using run.addPicture() method.

输出文件如下所示,

我想删除页边距并让该图像完全占据页眉。

【问题讨论】:

  • 请阅读How to create a Minimal, Reproducible Example。为了能够提供帮助,我们需要导致所描述问题的代码。 IE。您尝试创建在标题中包含图像的文档的代码。
  • Axel Richter,我相信这个问题描述得很好。只是,尝试使用 apache POI 将图像放置在 word 文档的标题部分。在这种情况下,我想忽略标题部分中的空白,以使图像完全占据标题部分。希望此评论对您有所帮助。
  • 没有代码,很难看出你做错了什么......没有添加图片的代码,很难看出需要改变什么

标签: java apache-poi


【解决方案1】:

使用XWPFRun.addPicture 图像与文本内联,因此段落设置很重要。默认情况下,Word 段落后面有间距。使用XWPFParagraph.setSpacingAfter 可以将其设置为0。默认情况下,Word 段落在段落中的行之间具有间距。使用XWPFParagraph.setSpacingBetween可以设置为单行,所以段落中的行之间没有间距。

要使页眉中的图片出现在页面的绝对顶部,页首页边距需要为0。页眉和页边距之间的距离也需要为0。不幸的是,设置页面大小和页边距不是尚未在XWPF 中实施。所以我们需要使用org.openxmlformats.schemas.wordprocessingml.x2006.main.* 类。

图片左右的间距是图片的左边缘和左页边距之间的距离,分别是图片的右边缘和右页边距。这取决于图片的宽度。但我看不出如何在不违反图片纵横比的情况下消除这些间隙,从而扭曲图片。如果这是想要的,则将图片的宽度设置为适当的。

要使图片全宽,需要知道所需的宽度(以磅为单位)(pt)。那将是页边距之间页面的内部宽度。在我的示例中,8.5" 页面宽度 - 0.5" 左边距 - 0.5" 右边距 = 7.5"。

当然,也有左页边距和右页边距,从不应该设置为 0。这会使文档在大多数打印机上无法打印,因为打印机具有不可打印功能范围在左边。顶部、右侧和底部也有不可打印的范围,但这比左侧的不可打印范围更容易处理。要将内容从左页边距向右移动,必须移动每个单独的内容行。

因为将上边距设置为 0,所以会影响所有页面。因此,需要在其他页面的标题中添加一些内容以将正文内容向下移动。这可能是一些内容或后面有空格的空段落。

完整示例:

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.wp.usermodel.HeaderFooterType;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;

import java.math.BigInteger;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  // the body content - two pages
  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = document.createParagraph();
  run=paragraph.createRun();  
  run.setText("First Page....");
  
  paragraph = document.createParagraph();
  run=paragraph.createRun();  
  run.addBreak(BreakType.PAGE);

  paragraph = document.createParagraph();
  run=paragraph.createRun();  
  run.setText("Second Page....");
    
  
  // first page header
  XWPFHeader header = document.createHeader(HeaderFooterType.FIRST);

  paragraph = header.getParagraphArray(0);
  if (paragraph == null) paragraph = header.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);
  
  // set spacing after paragraph 0
  paragraph.setSpacingAfter(0);
  // set spacing between lines in paragraph to 1 (single)
  paragraph.setSpacingBetween(1d, LineSpacingRule.AUTO);

  // the image is inline with text so the paragraph settings matters
  run = paragraph.createRun();  
  String imgFile="./laptop.jpg";

  // calculate page inner width to set the picture's width the same
  long pageInnerWidthPt = Math.round(7.5 * 72d); //8.5" page width - 0.5" left margin - 0.5" right margin = 7.5"
  run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(pageInnerWidthPt), Units.toEMU(200));
  
  // default page header
  header = document.createHeader(HeaderFooterType.DEFAULT);
  paragraph = header.getParagraphArray(0);
  if (paragraph == null) paragraph = header.createParagraph();
  // set spacing after to 24 pt to shift the body down in default pages
  paragraph.setSpacingAfter(24*20);

  // create footer start
  XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);

  paragraph = footer.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");
  
  // create page margins
  CTSectPr sectPr = document.getDocument().getBody().getSectPr();
  if (sectPr == null) sectPr = document.getDocument().getBody().addNewSectPr();
  CTPageSz pageSz = sectPr.addNewPgSz(); // paper format letter
  pageSz.setW(BigInteger.valueOf(12240)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
  pageSz.setH(BigInteger.valueOf(15840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"
  CTPageMar pageMar = sectPr.getPgMar();
  if (pageMar == null) pageMar = sectPr.addNewPgMar();
  pageMar.setLeft(BigInteger.valueOf(720)); //720 TWentieths of an Inch Point (Twips) = 720/20 = 36 pt = 36/72 = 0.5"
  pageMar.setRight(BigInteger.valueOf(720));
  // set top page margin 0, so header can be at absolute top
  pageMar.setTop(BigInteger.valueOf(0));
  //pageMar.setBottom(BigInteger.valueOf(0));
  //pageMar.setFooter(BigInteger.valueOf(0));
  // set distance between header and page margin 0, so header starts at absolute top
  pageMar.setHeader(BigInteger.valueOf(0));
  //pageMar.setGutter(BigInteger.valueOf(0));

  FileOutputStream out = new FileOutputStream("./test.docx");
  document.write(out);
  out.close();
  document.close();

 }
}

结果:

只有左边的空白是左边的页边距,不应该被触摸。而且只有右边的空白是右边的页边距,也不能碰。

【讨论】:

  • 即使我增加了图像的宽度,上述解决方案也不能解决左边距问题(但是当宽度增加时,图像右侧的空白区域会被图像填充)。左侧的空白仍然存在。此外,如果我将 pageMar.setTop 设置为 0,则第二、第三页(没有任何标题)中的内容也会从绝对顶部显示,就像图像显示在屏幕截图中一样。有什么可能的解决方案吗?
  • @Kishore:您将如何使用 Microsoft Word GUI 满足您的要求? Apache POI 无法创建 Microsoft Word 无法创建的 Word 文档。
  • 明白你的意思。图像左侧的那个空白问题怎么样,有什么可能吗?还是那太不可能了?请指教,谢谢。
  • @Kishore:我的答案有所改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多