Estoy usando PDFDomTree con PDFBox-2.0.9 en mi aplicación Java para convertir un archivo PDF a un archivo HTML. Siguiente código que he utilizado para convertir un pdf.
try {
PDDocument document = PDDocument.load(new File("some path"));
PDFDomTree parser = new PDFDomTree(PDFDomTreeConfig.createDefaultConfig());
Writer output = new PrintWriter(new File("some output path"), "utf-8");
parser.writeText(document, output);
output.close();
document.close();
} catch (IOException | ParserConfigurationException e) {
throw e;
}
Ahora mi problema es cuando traté de analizar HTML de salida, me di cuenta de que el convertidor no fue capaz de detectar los espacios en blanco entre dos palabras, debido a que me dieron algunas palabras concatenadas.
Comprueba la siguiente comparación:
Correspondiente archivo pdf se puede acceder desde aquí , si es necesario.
¿Puede alguien por favor me ayude con esto?
El extractor de texto que nos ocupa, de Pdf2Dom PDFDomTree
, se basa en PDFBox' PDFTextStripper
pero sólo lo utiliza para analizar el dibujo PDF instrucciones en personajes con estilo y posición mientras se hace todo el análisis de estos personajes en sí ricos.
En particular, se ignora todos los caracteres de espacio en blanco entrantes en la PDFBoxTree
clase padre:
protected void processTextPosition(TextPosition text)
{
if (text.isDiacritic())
{
lastDia = text;
}
else if (!text.getUnicode().trim().isEmpty())
{
[...process character...]
}
}
( org.fit.pdfdom.PDFBoxTree
Override processTextPosition
)
En ese [...process character...]
bloque se trata de reconocer las brechas de palabras por distancias cifrados duros:
//should we split the boxes?
boolean split = lastText == null || distx > 1.0f || distx < -6.0f || Math.abs(disty) > 1.0f
|| isReversed(getTextDirectionality(text)) != isReversed(getTextDirectionality(lastText));
(dentro de la [...process character...]
cuadra arriba)
A medida que el texto en el PDF es pequeño para empezar (9 puntos determinado por Pdf2Dom) y en muchas líneas muy firmemente establecido, espacios entre palabras por lo general son más pequeños que el 1.0
supuesto anteriormente ( distx > 1.0f
).
En mis ojos hay un 2 ediciones aquí:
dejar caer espacios blanco significa que lanzan la información de distancia; (En algunas situaciones esto podría ser ventajoso, he visto los archivos PDF con la misma línea dibujada dos veces con alguno de los argumentos cadena de dibujo que contiene espacios en los que el otro contiene caracteres visibles, pero estas son excepciones).
que tiene límites de distancia codificadas de forma rígida
distx > 1.0f
,distx < -6.0f
, etc., aunque los tamaños de fuente (y con ellos los tamaños GAP) puede variar mucho.
Estas cuestiones deben fijarse en el código. Dos posibles soluciones temporales para archivos PDF como su demo.pdf:
La elección de diferentes límites de distancia
Una solución verdadera debe tratar de hacer la dinámica límites de distancia, dependiendo del tamaño de la fuente y probablemente incluso la distancia promedio de los caracteres en la línea actual hasta la posición actual. Una solución alternativa para el PDF sería sustituir la distancia codificado por una sola codificado más pequeño.
Por ejemplo, usando .5f
en lugar de la 1.0f
como palabra distancia, es decir, la sustitución de la prueba anterior por
//should we split the boxes?
boolean split = lastText == null || distx > .5f || distx < -6.0f || Math.abs(disty) > 1.0f
Este resultado en el reconocimiento de la palabra Pdf2Dom lagunas en el documento (o al menos muchos más, no he comprobado todos ellos).
Interpretación de los espacios en blanco como escisiones
En lugar de ignorar espacios en blanco, se puede interpretar de forma explícita como las lagunas de palabras, por ejemplo, mediante la mejora de la processTextPosition
anulación como esto
protected void processTextPosition(TextPosition text)
{
if (text.isDiacritic())
{
lastDia = text;
}
else if (!text.getUnicode().trim().isEmpty())
{
[...process character...]
} else {
//!! process white spaces here
//finish current box (if any)
if (lastText != null)
{
finishBox();
}
//start a new box
curstyle = new BoxStyle(style);
lastText = null;
}
}
No he analizado el código en profundidad, lo que sólo puede llamar a esto una solución temporal. Para que sea una verdadera solución, hay que probarlo para los efectos secundarios y también extenderlo a mirada en la naturaleza exacta de los espacios en blanco: Hay otros caracteres de espacio en blanco que el espacio normal, algunas de ellas de ancho cero, algunos no -breaking, etc. Todos estos diferentes tipos de espacios en blanco merece un tratamiento especial.
PD: Como muchos PDFBoxTree
miembros están protegidos (y no privado), es fácilmente posible aplicar la segunda solución alternativa sin tener que Pdf2Dom parche:
PDDocument document = PDDocument.load(SOURCE);
PDFDomTree parser = new PDFDomTree(PDFDomTreeConfig.createDefaultConfig()) {
@Override
protected void processTextPosition(TextPosition text) {
if (text.getUnicode().trim().isEmpty()) {
//finish current box (if any)
if (lastText != null)
{
finishBox();
}
//start a new box
curstyle = new BoxStyle(style);
lastText = null;
} else {
super.processTextPosition(text);
}
}
};
Writer output = new PrintWriter(TARGET, "utf-8");
parser.writeText(document, output);
output.close();
( ExtractText prueba testDemoImproved
)