Created
July 4, 2022 07:47
-
-
Save mjm918/765facc65ab451b118a0987547095ef8 to your computer and use it in GitHub Desktop.
Oppo/Vivo Android WebView font bug fixed react-native-html-to-pdf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
implementation 'com.itextpdf:itext7-core:7.1.8' | |
implementation 'com.itextpdf:html2pdf:2.0.1' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PDFGenManager extends ReactContextBaseJavaModule { | |
private static final String TAG = "PDFGenManager"; | |
private ReactApplicationContext context; | |
private File directory; | |
private String dirPath; | |
private PDFConverter convertor; | |
public PDFGenManager(@NonNull ReactApplicationContext reactContext) { | |
super(reactContext); | |
this.context = reactContext; | |
File storage = reactContext.getFilesDir(); | |
File folder = new File(storage.getAbsoluteFile(), "/Downloads/PDFs/"); | |
this.directory = new File(folder.getAbsolutePath()); | |
if(!this.directory.exists()){ | |
Log.i(TAG,"/Downloads/PDFs -- does not exists"); | |
this.directory.mkdirs(); | |
} | |
this.dirPath = directory.getPath().concat(File.separator); | |
} | |
@ReactMethod | |
public void convert(ReadableMap options, Callback success, Callback failed){ | |
if (!options.hasKey("html") || options.getString("html") == null){ | |
failed.invoke(this.onError("No `html` content found",1404)); | |
return; | |
} | |
if (!options.hasKey("fileName") || options.getString("fileName") == null){ | |
failed.invoke(this.onError("No `fileName` found",1405)); | |
return; | |
} | |
final String fileName = options.getString("fileName"); | |
String dest = this.dirPath.concat(fileName.concat(".pdf")); | |
String tmpHtmlDest = this.dirPath.concat(fileName.concat(".html")); | |
FileOutputStream outputStream = new FileOutputStream(tmpHtmlDest); | |
outputStream.write(options.getString("html").getBytes(StandardCharsets.UTF_8)); | |
outputStream.flush(); | |
outputStream.close(); | |
ByteArrayOutputStream pdf = createPdf(tmpHtmlDest); | |
if (pdf != null){ | |
scalePdf(dest, new ByteArrayInputStream(pdf.toByteArray()), 0.7071f); | |
File tmpFile = new File(tmpHtmlDest); | |
if (tmpFile.exists()){ | |
tmpFile.delete(); | |
} | |
success.invoke(onSuccess(dest)); | |
} else { | |
Log.e(TAG,"ByteArrayOutputStream pdf -- is empty"); | |
failed.invoke(onError("ByteArrayOutputStream pdf -- is empty",1098)); | |
} | |
} catch (IOException e){ | |
Log.e(TAG,e.getMessage()); | |
failed.invoke(onError(e.getMessage(),1099)); | |
} | |
} | |
private WritableMap onError(String message, int code){ | |
WritableMap map = new WritableNativeMap(); | |
map.putString("error",message); | |
map.putInt("code",code); | |
return map; | |
} | |
private WritableMap onSuccess(String path){ | |
WritableMap map = new WritableNativeMap(); | |
map.putString("filePath",path); | |
return map; | |
} | |
@NonNull | |
@Override | |
public String getName() { | |
return "PDFGenerator"; | |
} | |
public static ByteArrayOutputStream createPdf(String htmlSrc) { | |
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
ConverterProperties converterProperties = new ConverterProperties(); | |
converterProperties.setBaseUri(new File(htmlSrc).getParent()); | |
PdfWriter writer = new PdfWriter(output); | |
PdfDocument pdfDocument = new PdfDocument(writer); | |
PdfMerger merger = new PdfMerger(pdfDocument); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
PdfDocument temp = new PdfDocument(new PdfWriter(baos)); | |
temp.setDefaultPageSize(PageSize.A3); | |
try{ | |
HtmlConverter.convertToPdf(new FileInputStream(htmlSrc), temp, converterProperties); | |
temp = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray()))); | |
merger.merge(temp, 1, temp.getNumberOfPages()); | |
temp.close(); | |
pdfDocument.close(); | |
return output; | |
} catch (IOException e){ | |
Log.e(TAG,e.getMessage()); | |
return null; | |
} | |
} | |
public void scalePdf(String dest, ByteArrayInputStream input, float scale) throws IOException { | |
PdfDocument srcDoc = new PdfDocument(new PdfReader(input)); | |
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest)); | |
ScaleDownEventHandler eventHandler = new ScaleDownEventHandler(scale); | |
int n = srcDoc.getNumberOfPages(); | |
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, eventHandler); | |
PdfCanvas canvas; | |
PdfFormXObject page; | |
for (int p = 1; p <= n; p++) { | |
eventHandler.setPageDict(srcDoc.getPage(p).getPdfObject()); | |
canvas = new PdfCanvas(pdfDoc.addNewPage()); | |
page = srcDoc.getPage(p).copyAsFormXObject(pdfDoc); | |
canvas.addXObject(page, scale, 0f, 0f, scale, 0f, 0f); | |
} | |
pdfDoc.close(); | |
srcDoc.close(); | |
} | |
protected class ScaleDownEventHandler implements IEventHandler { | |
protected float scale = 1; | |
protected PdfDictionary pageDict; | |
public ScaleDownEventHandler(float scale) { | |
this.scale = scale; | |
} | |
public void setPageDict(PdfDictionary pageDict) { | |
this.pageDict = pageDict; | |
} | |
@Override | |
public void handleEvent(Event event) { | |
PdfDocumentEvent docEvent = (PdfDocumentEvent) event; | |
PdfPage page = docEvent.getPage(); | |
page.put(PdfName.Rotate, pageDict.getAsNumber(PdfName.Rotate)); | |
scaleDown(page, pageDict, PdfName.MediaBox, scale); | |
scaleDown(page, pageDict, PdfName.CropBox, scale); | |
} | |
protected void scaleDown(PdfPage destPage, PdfDictionary pageDictSrc, PdfName box, float scale) { | |
PdfArray original = pageDictSrc.getAsArray(box); | |
if (original != null) { | |
float width = original.getAsNumber(2).floatValue() - original.getAsNumber(0).floatValue(); | |
float height = original.getAsNumber(3).floatValue() - original.getAsNumber(1).floatValue(); | |
PdfArray result = new PdfArray(); | |
result.add(new PdfNumber(0)); | |
result.add(new PdfNumber(0)); | |
result.add(new PdfNumber(width * scale)); | |
result.add(new PdfNumber(height * scale)); | |
destPage.put(box, result); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment