我想使用PDFBox API将文本添加到PDF,并将其旋转45度,然后将其放置在页面的中心,文本是动态的,应始终放置在中心,除居中部分外,其他所有工作,我们将不胜感激.
我有以下代码:
Point2D.Float pageCenter = getCenter(page);
float stringWidth = getStringWidth(watermarkText, font, fontSize);
float textX = pageCenter.x - stringWidth / 2F + center.x;
System.out.println(textX);
float textY = pageCenter.y + center.y;
//System.out.println("Inside cross"+textX+", "+textY);
fontSize = 110.0f;
cs.transform(Matrix.getRotateInstance(Math.toRadians(45), textX, textY));
cs.moveTo(0, 0);
cs.lineTo(125, 0);
r0.setNonStrokingAlphaConstant(0.20f);
这是我想要的结果:
Output PDF
解决方法:
我要做的是首先根据计算出的角度旋转.在这个“旋转的世界”中,我做了一个水平偏移,以使文本位于中间,并且也将文本垂直向下移动一点,以便使其位于想象的对角线的“垂直”中间(“旋转的世界”).
try (PDDocument doc = new PDDocument())
{
PDPage page = new PDPage();
doc.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
try (PDPageContentStream cs =
new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true))
// use this long constructor when working on existing PDFs
{
float fontHeight = 110;
String text = "Watermark";
float width = page.getMediaBox().getWidth();
float height = page.getMediaBox().getHeight();
int rotation = page.getRotation();
switch (rotation)
{
case 90:
width = page.getMediaBox().getHeight();
height = page.getMediaBox().getWidth();
cs.transform(Matrix.getRotateInstance(Math.toRadians(90), height, 0));
break;
case 180:
cs.transform(Matrix.getRotateInstance(Math.toRadians(180), width, height));
break;
case 270:
width = page.getMediaBox().getHeight();
height = page.getMediaBox().getWidth();
cs.transform(Matrix.getRotateInstance(Math.toRadians(270), 0, width));
break;
default:
break;
}
float stringWidth = font.getStringWidth(text) / 1000 * fontHeight;
float diagonalLength = (float) Math.sqrt(width * width + height * height);
float angle = (float) Math.atan2(height, width);
float x = (diagonalLength - stringWidth) / 2; // "horizontal" position in rotated world
float y = -fontHeight / 4; // 4 is a trial-and-error thing, this lowers the text a bit
cs.transform(Matrix.getRotateInstance(angle, 0, 0));
cs.setFont(font, fontHeight);
//cs.setRenderingMode(RenderingMode.STROKE); // for "hollow" effect
PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
gs.setNonStrokingAlphaConstant(0.2f);
gs.setStrokingAlphaConstant(0.2f);
gs.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
// gs.setBlendMode(BlendMode.MULTIPLY); // will work in 2.0.14
cs.setGraphicsStateParameters(gs);
// some API weirdness here. When int, range is 0..255.
// when float, this would be 0..1f
cs.setNonStrokingColor(255, 0, 0);
cs.setStrokingColor(255, 0, 0);
cs.beginText();
cs.newLineAtOffset(x, y);
cs.showText(text);
cs.endText();
}
doc.save("watermarked.pdf");
}
请注意,我同时设置了描边和不描边(=填充).这对于想要尝试仅使用笔触的(空心)“空心”外观的人很有用.默认模式是填充,即不描边.