Maison > développement back-end > C++ > Comment éliminer les espaces blancs lors de la fusion de PDF ?

Comment éliminer les espaces blancs lors de la fusion de PDF ?

Mary-Kate Olsen
Libérer: 2024-12-25 22:43:09
original
522 Les gens l'ont consulté

How to Eliminate White Space When Merging PDFs?

Comment éliminer les espaces lors de la fusion

Question :

J'ai du code qui contient 3 tableaux d'octets PDF différents, et fusionnez-les. Ce code fonctionne bien. Certaines personnes ont des problèmes car chaque PDF est traité comme une page entière (s'il est imprimé), même s'il ne contient qu'environ 4 pouces de contenu, laissant 7 pouces d'espace blanc vertical. Ensuite, le document du milieu est inséré et ne peut comporter aucun espace vertical à la fin. Le pied de page est alors également placé sur sa propre page.

Voici le code :

byte[] Bytes = rv.LocalReport.Render("PDF", null, out MimeType, out Encoding, out Extension, out StreamIDs, out Warnings);
List<byte[]> MergeSets = // 在此代码之前填充

// 将任何其他页面附加到此主要信件
if (MergeSets.Count > 0)
{
    MemoryStream ms = new MemoryStream();
    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, ms);
    document.Open();
    PdfImportedPage page;
    PdfReader reader = new PdfReader(Bytes); // 读取生成的正文信
    int pages = reader.NumberOfPages;

    for (int i = 0; i < pages;)
    {
        page = copy.GetImportedPage(reader, ++i);
        copy.AddPage(page);
    } // 遍历所有正文信的页面

    // 现在附加合并集
    foreach (byte[] ba in MergeSets)
    {
        reader = new PdfReader(ba);
        pages = reader.NumberOfPages;

        for (int i = 0; i < pages;)
        {
            page = copy.GetImportedPage(reader, ++i);
            copy.AddPage(page);
        } // 遍历当前合并集中的所有页面
    } // 遍历数据集中所有内容

    document.Close();

    ServerSaved = SaveGeneratedLetter(ms.GetBuffer(), DateTime.Now.Year, hl.LetterName, SaveName);
} // 如果有待合并的任何内容
Copier après la connexion

Question :

Y a-t-il un moyen de couper/supprimer/supprimer lorsque je fusionne chaque page verticalement un espace blanc à la fin de chaque PDF pour qu'il apparaisse comme un seul document homogène ?

Mise à jour :

Voici des exemples de fichiers .pdf que j'essaie de fusionner.

Titre, corps, pied de page

Mise à jour 2 : Utilisation de la réponse :

J'ai converti le code de @mkl en C# comme indiqué ci-dessous.

La classe utilitaire :

public class PdfVeryDenseMergeTool
{

    private Rectangle PageSize;
    private float TopMargin;
    private float BottomMargin;
    private float Gap;
    private Document Document = null;
    private PdfWriter Writer = null;
    private float YPosition = 0;

    public PdfVeryDenseMergeTool(Rectangle size, float top, float bottom, float gap)
    {
        this.PageSize = size;
        this.TopMargin = top;
        this.BottomMargin = bottom;
        this.Gap = gap;
    } // PdfVeryDenseMergeTool

    public void Merge(MemoryStream outputStream, List<PdfReader> inputs)
    {
        try
        {
            this.OpenDocument(outputStream);

            foreach (PdfReader reader in inputs)
            {
                this.Merge(reader);
            } // 遍历待合并的 PDF 文件
        }
        finally
        {
            this.CloseDocument();
        } // try-catch-finally
    } // Merge

    public void OpenDocument(MemoryStream outputStream)
    {
        this.Document = new Document(PageSize, 36, 36, this.TopMargin, this.BottomMargin);
        this.Writer = PdfWriter.GetInstance(Document, outputStream);

        this.Document.Open();
        this.NewPage();
    } // OpenDocument

    public void CloseDocument()
    {
        try
        {
            this.Document.Close();
        }
        finally
        {
            this.Document = null;
            this.Writer = null;
            this.YPosition = 0;
        } // try-finally
    } // CloseDocument

    public void NewPage()
    {
        this.Document.NewPage();
        this.YPosition = PageSize.GetTop(this.TopMargin);
    } // Merge

    public void Merge(PdfReader reader)
    {
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);

        for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++)
        {
            this.Merge(reader, parser, pageIndex);
        } // 遍历当前 PDF 的所有页面
    } // Merge

    public void Merge(PdfReader reader, PdfReaderContentParser parser, int pageIndex)
    {
        PdfImportedPage importedPage = Writer.GetImportedPage(reader, pageIndex);
        PdfContentByte directContent = Writer.DirectContent;

        PageVerticalAnalyzer finder = parser.ProcessContent(pageIndex, new PageVerticalAnalyzer());

        if (finder.VerticalFlips.Count < 2)
            return;

        Rectangle pageSizeToImport = reader.GetPageSize(pageIndex);

        int startFlip = finder.VerticalFlips.Count - 1;
        bool first = true;

        while (startFlip > 0)
        {
            if (!first)
                this.NewPage();

            float freeSpace = this.YPosition - PageSize.GetBottom(BottomMargin);
            int endFlip = startFlip + 1;

            while ((endFlip > 1) && (finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip - 2] < freeSpace))
                endFlip -= 2;

            if (endFlip < startFlip)
            {
                float height = finder.VerticalFlips[startFlip] - finder.VerticalFlips[endFlip];

                directContent.SaveState();
                directContent.Rectangle(0, this.YPosition - height, pageSizeToImport.Width, height);
                directContent.Clip();
                directContent.NewPath();

                this.Writer.DirectContent.AddTemplate(importedPage, 0, this.YPosition - (finder.VerticalFlips[startFlip] - pageSizeToImport.Bottom));

                directContent.RestoreState();
                this.YPosition -= height + this.Gap;
                startFlip = endFlip - 1;
            }
            else if (!first)
            {
                throw new ArgumentException(string.Format("Page {0} content too large", pageIndex));
            } // if

            first = false;
        } // while
    } // Merge
} // PdfVeryDenseMergeTool
Copier après la connexion

La classe d'écoute de rendu :

Mise à jour 3 : Correction d'une ligne de code fonctionne désormais correctement : Voir les commentaires dans le code

public class PageVerticalAnalyzer : IRenderListener
{

    public PageVerticalAnalyzer()
    { }

    public List<float> VerticalFlips = new List<float>();

    public void AddVerticalUseSection(float from, float to)
    {
        if (to < from)
        {
            float temp = to;
            to = from;
            from = temp;
        }

        int i = 0;
        int j = 0;

        for (i = 0; i < VerticalFlips.Count; i++)
        {
            float flip = VerticalFlips[i];
            if (flip < from)
                continue;

            for (j = i; j < VerticalFlips.Count; j++)
            {
                flip = VerticalFlips[j];
                if (flip < to)
                    continue;
                break;
            }
            break;
        } // 遍历所有垂直翻转

        bool fromOutsideInterval = i % 2 == 0;
        bool toOutsideInterval = j % 2 == 0;

        while (j-- > i)
            VerticalFlips.RemoveAt(j); // 这是存在问题的代码行,只使用了 .Remove(j)
        if (toOutsideInterval)
            VerticalFlips.Insert(i, to);
        if (fromOutsideInterval)
            VerticalFlips.Insert(i, from);
    } // AddVerticalUseSection

    public void BeginTextBlock()
    { /* Do nothing */ }

    public void EndTextBlock()
    { /* Do nothing */ }

    public void RenderImage(ImageRenderInfo renderInfo)
    {
        Matrix ctm = renderInfo.GetImageCTM();
        List<float> YCoords = new List<float>(4) { 0, 0, 0, 0 };

        for (int x = 0; x < 2; x++)
        {
            for (int y = 0; y < 2; y++)
            {
                Vector corner = new Vector(x, y, 1).Cross(ctm);
                YCoords[2 * x + y] = corner[Vector.I2];
            }
        }

        YCoords.Sort();
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal