我使用Apache的PDFBox库编写了一个PdfDocumentBuilder类。在尝试将字符写入文件之前,我使用currentFont.hasGlyph(character)
检查字符是否有字形。问题是当字符是像'\u001f'
这样的unicode控制字符时,hasGlyph()
返回true,导致encode()
在写入时抛出异常(参见下面的PdfDocumentBuilder代码和堆栈跟踪)参考)。
我做了一些研究,看来这些unicode控制字符不支持我使用的字体(Courier Prime)。
那么为什么hasGlyph()
在不支持unicode控制字符时会返回true?当然,在我输入replaceAll
方法之前,我可以使用简单的writeTextWithSymbol()
从行中删除控制字符,但如果hasGlyph()
方法没有按照我预期的方式工作,我有一个更大的问题。
PdfDocumentBuilder:
private final PDType0Font baseFont;
private PDType0Font currentFont;
public PdfDocumentBuilder () {
baseFont = PDType0Font.load(doc, this.getClass().getResourceAsStream("/CourierPrime.ttf"));
currentFont = baseFont;
}
private void writeTextWithSymbol (String text) throws IOException {
StringBuilder nonSymbolBuffer = new StringBuilder();
for (char character : text.toCharArray()) {
if (currentFont.hasGlyph(character)) {
nonSymbolBuffer.append(character);
} else {
//handling writing line with symbols...
}
}
if (nonSymbolBuffer.length() > 0) {
content.showText(nonSymbolBuffer.toString());
}
}
堆栈追踪:
java.lang.IllegalArgumentException: No glyph for U+001F in font CourierPrime
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:400)
at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:351)
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:316)
at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:414)
at org.main.export.PdfDocumentBuilder.writeTextWithSymbol(PdfDocumentBuilder.java:193)
答案 0 :(得分:4)
正如上面的评论中所解释的,using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
char choice = '7';
while (choice != '3')
{
Console.WriteLine("---------------Calculator---------------");
Console.WriteLine("\n1.Add\n2.Subtract\n3.Multiply\n4.Divide\n5.Modulo-Operation (remainder)\n6.Exit\n");
Console.WriteLine("Enter your choice:");
choice = Convert.ToChar(Console.Read());
switch (choice)
{
case '1':
Calculator.Add();
break;
case '2':
Calculator.Subtract();
break;
case '3':
Calculator.Multiply();
break;
case '4':
Calculator.Divide();
break;
case '5':
Calculator.Modulo();
break;
case '6':
Environment.Exit(0);
break;
default:
Console.WriteLine("Invalid Choice.\n");
break;
}
}
}
}
class Calculator
{
public static void Add()
{
int a, b;
string sa, sb;
Console.WriteLine("Enter the first number:\n");
sa = Console.ReadLine().Trim();
a = Convert.ToInt32(sa);
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
Console.Write("{0}\n", a + b);
}
public static void Subtract()
{
int a, b;
string sa, sb;
Console.WriteLine("Enter the first number:\n");
sa = Console.ReadLine().Trim();
a = Convert.ToInt32(sa);
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
Console.Write("{0}\n", a - b);
}
public static void Multiply()
{
int a, b;
string sa, sb;
Console.WriteLine("Enter the first number:\n");
sa = Console.ReadLine().Trim();
a = Convert.ToInt32(sa);
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
Console.Write("{0}\n", a * b);
}
public static void Divide()
{
int a, b;
string sa,sb;
Console.WriteLine("Enter the first number:\n");
sa = Console.ReadLine().Trim();
a = Convert.ToInt32(sa);
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
while (b == 0)
{
Console.WriteLine("In division operation, divisor cannot be zero.\n Retry!!\n");
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
}
Console.Write("{0}\n", a / b);
}
public static void Modulo()
{
int a, b;
string sa, sb;
Console.WriteLine("Enter the first number:\n");
sa = Console.ReadLine().Trim();
a = Convert.ToInt32(sa);
while (a < 0)
{
Console.WriteLine("In modulo operation, first number cannot be negative.\n Retry!!\n");
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
}
Console.WriteLine("Enter the second number:\n");
sb = Console.ReadLine().Trim();
b = Convert.ToInt32(sb);
Console.Write("{0}\n", a % b);
}
}
}
并不意味着接受unicode字符作为参数。因此,如果您需要在编写字符之前检查字符是否可以编码,您可以执行以下操作:
hasGlyph()