方法1:使用iText中文支持包(见附件iTextAsian-for-5.x-1.0)然后重新设置表单字体即可
if (fields.getFields() != null || !fields.getFields().isEmpty()) {// change field
ByteArrayOutputStream exchangeByteOut = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(originReader, exchangeByteOut);
fields = stamper.getAcroFields();
Set<String> keys = fields.getFields().keySet();
// BaseFont bfChinese =
// BaseFont.createFont("C:/Windows/Fonts/kaiu.ttf", BaseFont.IDENTITY_H,
// BaseFont.NOT_EMBEDDED); // the file become very large
BaseFont bfChinese =
BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); // iTextAsian-for-5.x.jar
for (String name : keys) {
if (name == null || name.length() <= 0)
continue;
AcroFields.Item item = fields.getFieldItem(name);
// log.info(name +"'s font is"+PDFUtils.FONT_ArialUnicodeMS);
String value = fields.getField(name);
// set the font to default
fields.setFieldProperty(name, "textfont", bfChinese/* BaseFont.createFont() */, null);
fields.setField(name, value);// reset value
}
exchangeByteOut.flush();
exchangeByteOut.close();
stamper.close();
originReader = new PdfReader(exchangeByteOut.toByteArray());
....
使用 PdfCopyFields直接拷贝,合并文档
byteOutStream = new ByteArrayOutputStream();
PdfCopyFields copyFields = new PdfCopyFields(byteOutStream);
copyFields.addDocument(originReader);
copyFields.addDocument(signTempleteReader);
copyFields.close();
方法2:把表单去掉
如果进行直接用PdfCopy带form的PDF,TextField字段会出现乱.所以要先把其处理为文本
public static PdfReader processTextField(InputStream docIns) throws IOException,
DocumentException {
PdfReader reader = new PdfReader(docIns);
AcroFields form = reader.getAcroFields();//read only
Map<String, Item> fields = form.getFields();
if (fields == null || fields.isEmpty())
return reader;
System.out.println(">>>>>>>>>Existing form.");
ByteArrayOutputStream exchangeByteOut = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, exchangeByteOut);
form=stamper.getAcroFields();//can edit form
// find the filed name
Set<Entry<String, Item>> fieldSet = fields.entrySet();
List<String> keys = new ArrayList<String>();
for (Entry<String, Item> entry : fieldSet) {
String key = entry.getKey();
keys.add(key);
}
// replace the field or set read only
AcroFields.Item item;
PdfDictionary dict;
int fieldAlign = Element.ALIGN_LEFT;
int flags;
for (String k : keys) {//
item = form.getFieldItem(k);
fieldAlign = PDFUtils.getItemAlignment(item);
dict = item.getMerged(0);
int fieldType = form.getFieldType(k);
PdfNumber pdfNum = dict.getAsNumber(PdfName.FF);
flags = pdfNum == null ? 0 : pdfNum.intValue();
if ((flags & BaseField.PASSWORD) > 0)
// System.out.println(" -> password");
if ((flags & BaseField.MULTILINE) > 0) {
// System.out.println(" -> multiline");
}
String fieldValue = form.getField(k);
float textSize = PDFUtils.getDefaultTextSize(item);
//System.out.println(k + "-->" + fieldValue + ",textSize:" + textSize);
List<FieldPosition> pos = form.getFieldPositions(k);
if (pos == null || pos.isEmpty())
continue;
FieldPosition p = pos.get(0);
Rectangle rect = p.position;
if (fieldType == AcroFields.FIELD_TYPE_TEXT) {// a text field
PdfContentByte content;
content = stamper.getOverContent(p.page);
ColumnText ct = new ColumnText(content);
ct.setSimpleColumn(new Phrase(new Chunk(fieldValue, FontFactory.getFont(
FontFactory.HELVETICA, textSize))), rect.getLeft(), rect.getBottom(), rect.getRight(),
rect.getTop(), 9, fieldAlign);
ct.go();
form.removeField(k);// remave the field
} else {
// log.info("it is't a text field,to set read only mode.Type:" + PDFUtils.getFormType(fieldType));
form.setFieldProperty(k, "setfflags", PdfFormField.FF_READ_ONLY, null);
}
}
stamper.close();
ByteArrayInputStream byteIn = new ByteArrayInputStream(exchangeByteOut.toByteArray());
reader = new PdfReader(byteIn);
return reader;
}
/**
public class PDFUtils {
public static final String FONT_ArialUnicodeMS="ArialUnicodeMS";
/**
* get AcroFields.Item align
*
* @param item
* @return
*/
public static int getItemAlignment(AcroFields.Item item) {
int res = Element.ALIGN_LEFT;
try {
PdfNumber nfl = item.getMerged(0).getAsNumber(PdfName.Q);
switch (nfl.intValue()) {
case PdfFormField.Q_CENTER:
res = Element.ALIGN_CENTER;
break;
case PdfFormField.Q_RIGHT:
res = Element.ALIGN_RIGHT;
break;
case PdfFormField.Q_LEFT:
default:
res = Element.ALIGN_LEFT;
}
} catch (NullPointerException e) {
res = Element.ALIGN_LEFT;
} finally {
return res;
}
}
public static String getFormType(int type) {
String name = "unknow type";
switch (type) {
case AcroFields.FIELD_TYPE_CHECKBOX:
name = "Checkbox";
break;
case AcroFields.FIELD_TYPE_COMBO:
name = "Combobox";
break;
case AcroFields.FIELD_TYPE_LIST:
name = "List";
break;
case AcroFields.FIELD_TYPE_NONE:
name = "None";
break;
case AcroFields.FIELD_TYPE_PUSHBUTTON:
name = "Pushbutton";
break;
case AcroFields.FIELD_TYPE_RADIOBUTTON:
name = "Radiobutton";
break;
case AcroFields.FIELD_TYPE_SIGNATURE:
name = "Signature";
break;
case AcroFields.FIELD_TYPE_TEXT:
name = "Text";
break;
default:
name = "unknow type";
}
return name;
}
public static float getTextSize(AcroFields.Item item) {
final int DA_SIZE = AcroFields.DA_SIZE;
PdfString da = item.getMerged(0).getAsString(PdfName.DA);
Object dab[] = AcroFields.splitDAelements(da.toUnicodeString());
for (Object object : dab) {
System.out.println("dab:" + object);
}
System.out.println("font:" + dab[AcroFields.DA_FONT]);
float size = ((Float) dab[DA_SIZE]).floatValue();
if (size <= 0) {// set default font size.
size = 9;
}
return size;
}
public static String getTextFont(AcroFields.Item item) {
PdfString da = item.getMerged(0).getAsString(PdfName.DA);
Object dab[] = AcroFields.splitDAelements(da.toUnicodeString());
return (String) dab[AcroFields.DA_FONT];
}
// public static String getTextColor(AcroFields.Item item) {
// PdfString da = item.getMerged(0).getAsString(PdfName.DA);
// Object dab[] = AcroFields.splitDAelements(da.toUnicodeString());
// return (C) dab[AcroFields.DA_COLOR];
// }
}