iText5 和 iText7 中文本绝对定位的差异
Difference in absolute positioning of Text in iText5 and iText7
我正在尝试从 iText5
迁移到 iText7
,但是文本的绝对定位存在问题。即使在对 iText5 和 iText7 进行完全相同的测量后,相同文本的相对位置似乎仍有相当大的偏移量。
这是显示问题的代码:
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iText.Kernel.Font;
namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
//using iText7
var folder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var fileName = "iText7.pdf";
var workingName = "iText5.pdf";
var finalPath = System.IO.Path.Combine(folder, fileName);
var WorkingFile = System.IO.Path.Combine(folder, workingName);
var pdfWriter = new iText.Kernel.Pdf.PdfWriter(finalPath);
var pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfWriter);
var doc = new iText.Layout.Document(pdfDoc, new iText.Kernel.Geom.PageSize(620.986F, 813.543F));
var font = PdfFontFactory.CreateRegisteredFont("HELVETICA", BaseFont.CP1252, false);
doc.SetMargins(0, 0, 0, 0);
doc.PutText(new iText.Layout.Element.Paragraph("TESTLINE").SetFont(font), ConvertCoords(189, 10));
doc.Flush();
doc.Close();
//using iText5
using (var FS = new FileStream(WorkingFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var Doc = new iTextSharp.text.Document(new iTextSharp.text.Rectangle(620.986F, 813.543F), 0, 0, 0, 0))
{
using (var Writer = iTextSharp.text.pdf.PdfWriter.GetInstance(Doc, FS))
{
Doc.Open();
Doc.NewPage();
var pcb = Writer.DirectContent;
pcb.BeginText();
//var font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
var fontbold = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, false);
pcb.SetFontAndSize(fontbold, 12);
pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "TESTLINE", (float)ConvertCoords(189, 10).GetX(), (float)ConvertCoords(189, 10).GetY(), 0);
pcb.EndText();
Writer.Flush();
Doc.Close();
}
}
}
}
private static void PutText(this iText.Layout.Document doc, iText.Layout.Element.Paragraph text, Point coords,
iText.Layout.Properties.TextAlignment horizontalalign = iText.Layout.Properties.TextAlignment.LEFT,
iText.Layout.Properties.VerticalAlignment verticalalign = iText.Layout.Properties.VerticalAlignment.TOP)
{
doc.ShowTextAligned(text, (float)coords.GetX(), (float)coords.GetY(), horizontalalign, verticalalign);
}
//Converts mm to Point
private static Point ConvertCoords(float a, float b)
{
return new Point(a * 2.834265, (287 - b) * 2.834645669291);
}
}
}
我正在使用 C#。谁能好心解决这个问题?否则,我将不得不承担一项艰巨的任务来重新测量所有表格。
编辑:
根据建议,我纠正了使用两种不同页面大小的疏忽。我已经在上面编辑了我的代码。但是,问题依然存在。
不幸的是,我只能解释行为的原因,但不知道解决它的非低级 iText 7 API 方法。
除了文档大小之间的微小差异(620.986F x 813.543F
对于您的 iText 5 代码,619.2f x 813.6f
对于您的 iText 7 代码)定位差异的主要原因是
- 对于您的 iText 5 代码,
PdfContentByte.ShowTextAligned
调用的 y 坐标表示 基线 文本 而
- 对于您的 iText 7 代码,默认情况下您的
PutText
方法调用的 y 坐标表示 顶部 的文本 (因为您默认分配值 iText.Layout.Properties.VerticalAlignment.TOP
)。
从 iText 5 移植到 iText 7 时,要寻找的明显解决方案是基线垂直对齐。
不过据我所知,不幸的是,iText 7 目前只知道以下垂直对齐值
public enum VerticalAlignment {
TOP,
MIDDLE,
BOTTOM
}
由于基线通常位于中间和底部之间的某处,但几乎不会与其中任何一条重合,因此缺少您要查找的垂直对齐方式。
因此,您实际上必须像 iText 7 TextRenderer
class 那样计算文本行的升序,并将其添加到 y TOP
对齐文本的坐标参数。或者编写一个新的文本渲染器,它 而不是 由上升器开始偏移。
我正在尝试从 iText5
迁移到 iText7
,但是文本的绝对定位存在问题。即使在对 iText5 和 iText7 进行完全相同的测量后,相同文本的相对位置似乎仍有相当大的偏移量。
这是显示问题的代码:
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iText.Kernel.Font;
namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
//using iText7
var folder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var fileName = "iText7.pdf";
var workingName = "iText5.pdf";
var finalPath = System.IO.Path.Combine(folder, fileName);
var WorkingFile = System.IO.Path.Combine(folder, workingName);
var pdfWriter = new iText.Kernel.Pdf.PdfWriter(finalPath);
var pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfWriter);
var doc = new iText.Layout.Document(pdfDoc, new iText.Kernel.Geom.PageSize(620.986F, 813.543F));
var font = PdfFontFactory.CreateRegisteredFont("HELVETICA", BaseFont.CP1252, false);
doc.SetMargins(0, 0, 0, 0);
doc.PutText(new iText.Layout.Element.Paragraph("TESTLINE").SetFont(font), ConvertCoords(189, 10));
doc.Flush();
doc.Close();
//using iText5
using (var FS = new FileStream(WorkingFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var Doc = new iTextSharp.text.Document(new iTextSharp.text.Rectangle(620.986F, 813.543F), 0, 0, 0, 0))
{
using (var Writer = iTextSharp.text.pdf.PdfWriter.GetInstance(Doc, FS))
{
Doc.Open();
Doc.NewPage();
var pcb = Writer.DirectContent;
pcb.BeginText();
//var font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
var fontbold = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, false);
pcb.SetFontAndSize(fontbold, 12);
pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "TESTLINE", (float)ConvertCoords(189, 10).GetX(), (float)ConvertCoords(189, 10).GetY(), 0);
pcb.EndText();
Writer.Flush();
Doc.Close();
}
}
}
}
private static void PutText(this iText.Layout.Document doc, iText.Layout.Element.Paragraph text, Point coords,
iText.Layout.Properties.TextAlignment horizontalalign = iText.Layout.Properties.TextAlignment.LEFT,
iText.Layout.Properties.VerticalAlignment verticalalign = iText.Layout.Properties.VerticalAlignment.TOP)
{
doc.ShowTextAligned(text, (float)coords.GetX(), (float)coords.GetY(), horizontalalign, verticalalign);
}
//Converts mm to Point
private static Point ConvertCoords(float a, float b)
{
return new Point(a * 2.834265, (287 - b) * 2.834645669291);
}
}
}
我正在使用 C#。谁能好心解决这个问题?否则,我将不得不承担一项艰巨的任务来重新测量所有表格。
编辑:
根据建议,我纠正了使用两种不同页面大小的疏忽。我已经在上面编辑了我的代码。但是,问题依然存在。
不幸的是,我只能解释行为的原因,但不知道解决它的非低级 iText 7 API 方法。
除了文档大小之间的微小差异(620.986F x 813.543F
对于您的 iText 5 代码,619.2f x 813.6f
对于您的 iText 7 代码)定位差异的主要原因是
- 对于您的 iText 5 代码,
PdfContentByte.ShowTextAligned
调用的 y 坐标表示 基线 文本 而 - 对于您的 iText 7 代码,默认情况下您的
PutText
方法调用的 y 坐标表示 顶部 的文本 (因为您默认分配值iText.Layout.Properties.VerticalAlignment.TOP
)。
从 iText 5 移植到 iText 7 时,要寻找的明显解决方案是基线垂直对齐。
不过据我所知,不幸的是,iText 7 目前只知道以下垂直对齐值
public enum VerticalAlignment {
TOP,
MIDDLE,
BOTTOM
}
由于基线通常位于中间和底部之间的某处,但几乎不会与其中任何一条重合,因此缺少您要查找的垂直对齐方式。
因此,您实际上必须像 iText 7 TextRenderer
class 那样计算文本行的升序,并将其添加到 y TOP
对齐文本的坐标参数。或者编写一个新的文本渲染器,它 而不是 由上升器开始偏移。